Потом, возможно, различные атрибуты подтянуться для управления сериализацией… Новичкам - оно сложно. Всё равно, что объяснять 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;
Хочу написать, какими на мой взгляд должны быть современные функции/расширения для чтения типизированных файлов. Они бы могли допускать некий унифицированный вызов с параметром, определяющим коэффициент блокирования. Например, по умолчанию читается весь файл и создается массив записей, в котором вместо 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-параметр и массив тоже есть, но обычно предпочтительнее использовать перегрузки, возвращающие запись и массив. То есть во всех случаях кроме необходимости безбожной оптимизации.
Речь не о том, есть или нет, речь о включенном в язык (а не в библиотеку, требующую подключения) едином средстве для работы с типизированными файлами. Одна функция/расширение для чтения и вторая - для записи.