Блочное сохранение в типизированный файл

Потом, возможно, различные атрибуты подтянуться для управления сериализацией… Новичкам - оно сложно. Всё равно, что объяснять StreamReader и подобные вещи. Сразу новичку их понять - сложно, ибо, в какой то мере абстрактно и непривычно.

Как один учитель выразился, “мне бы им условный оператор объяснить…”. На той конференции, что в конце октября на мехмате ЮФУ проводилась.

Либо сделают так, чтобы при замене file of T на BlockFileOf<T> не нарушалась обратная совместимость. Точнее, чтобы file of T был псевдонимом для BlockFileOf<T>. Но - сделают ли и захотят ли - мне неизвестно.

BlockFileOf не позволяет создавать типизированные файлы строк, даже коротких. Этим он существенно проще file of T. Существенная часть школьных задач работает с

type R = record name: string[10]; age: integer; end;
var f: file of R;
2 лайка

Хочу написать, какими на мой взгляд должны быть современные функции/расширения для чтения типизированных файлов. Они бы могли допускать некий унифицированный вызов с параметром, определяющим коэффициент блокирования. Например, по умолчанию читается весь файл и создается массив записей, в котором вместо seek мы можем просто пользоваться индексом. Это решает проблему с самой кошмарной операцией - модификацией записи. Обычное присваивание вместо подвода записи поиском, чтения в буфер, корректировки, подвода предыдущей записи (при чтении мы же к следующей перешли) и собственно записи. Если нужно читать не всю запись - указываем количество записей, которое нужно прочитать, начиная от 1 (это моделирует работу в “старом стиле”) и до некоторого k - это удобный аналог блочного чтения. аналогично решается вопрос и с записью.

Да, эта простота нужна для оптимизации, чтоб BlockFileOf<T> справлялся со своей основной задачей - скоростью.

Но вообще с BlockFileOf<T> можно сохранять строки. Это сложнее чем у file of T, но легче, чем то что сейчас описано в справке (я много нового с того момента узнал). Хотя принцип всё тот же - использовать атрибуты чтоб ручками управлять записью и сделать из неё размерную строку.

Вы как то часто этот термин использовали, при чём он явно не одно и то же значит в этих 3 случаях. Объясните это подробнее.

С обёрткой так не получится, потому что:

type
  r = record
    b: byte;
  end;
  
  wrap = class
    a := new r[5];
    
    property val[i: integer]: r
    read a[i]
    write a[i] := value; default;
    
  end;
  
begin
  var w := new wrap;
  
  w[3].b += 1; //Ошибка: Нельзя присвоить левой части
  
end.

В этом коде понадобилось бы вызвать сразу и read и write свойства за 1 операцию. А компилятор это делать не хочет.

Поэтому в .Net единственный вариант - считать в обычный массив. Ну и с BlockFileOf<T> это просто:

uses BlockFileOfT;

begin
  var f := new BlockFileOf<integer>('file.bin');
  f.Reset;
  
  var a := f.Read(f.Size); // чтение всего файла в массив
  
end.

Это не я виноват, а Н.Вирт, придумавший термин record вместо уже установившееся в то время термина strucrure. И получатся, что когда говорим, что в процессе “write file” некий массив данных типа “record” можно “write” блоками, каждый из которых содержит некое количество “records”, то по-русски это звучит примерно как запись массива записей блоками по несколько записей.

Итак, изначальный смысл был такой, что по умолчанию считывается весь файл и из его содержимого формируется некий array of T, где Т = record. Это можно сделать, поскольку длина записи в типизированном файле фиксированная. Это идеальный вариант на сегодня: данные загнали в память и там обрабатываем. Но если вдруг возникает желание память поэкономить (для преподавателей со странностями и разных программ, “оптимальных по памяти”), то можно читать не весь файл сразу, а блоками, порождая sequence of T заданной длины в k элементов. И, наконец, при k = 1 имеем классическое чтение из файла по одной записи в буфер типа T - аналог Read(f, buf);

И это уже тоже давно есть:

uses BlockFileOfT;

begin
  var f := new BlockFileOf<integer>('file.bin');
  f.Reset;
  
  f.ToSeqBlocks; // возвращает sequence array of integer, так чтоб содержимое каждого массива было не больше 4КБ
  f.ToSeqBlocks(1024*1024*10); // то же самое, но теперь у каждого массива не больше 10 мегабайт
  
end.

И перегрузки Read, принимающие var-параметр и массив тоже есть, но обычно предпочтительнее использовать перегрузки, возвращающие запись и массив. То есть во всех случаях кроме необходимости безбожной оптимизации.

Речь не о том, есть или нет, речь о включенном в язык (а не в библиотеку, требующую подключения) едином средстве для работы с типизированными файлами. Одна функция/расширение для чтения и вторая - для записи.