uses BlockFileOfT;

type
  r1=record
    i:integer;
    r:real;
    
    constructor(i:integer; r:real);
    begin
      self.i := i;
      self.r := r;
    end;
    ///Переопределение того - как объекты типа r1 будет выписывать writeln
    function ToString:string; override :=
    $'r1({i}, {r})';
  end;

begin
//  var f: BlockFileOf<r1>;
//  f := new BlockFileOf<r1>; // В отличии от file of T - BlockFileOf<T> всегда надо инициализировать перед тем как использовать
//  f.Assign('temp.bin');
  var f := new BlockFileOf<r1>('temp.bin'); // эта строчка работает как предыдущие 3
  
  f.Rewrite; // Если навести мышку на метод (в данном случае .Rewrite) - показывает описание
  f.Write(new r1(123,123.456));
  f.Write(new r1(456,456.789));
  
//  f.Flush; // не обязательно - .Close вызывает .Flush перед тем как закрыть файл
  // После работы с файлом - надо его закрыть. Иначе:
  // 1. Часть данных может не сохраниться
  // 2. Изменять файл вне переменной f будет нельзя, пока f держит его открытым
  f.Close;
  
//  f.Assign('temp.bin'); // Не обязательно, файл остаётся привязан после закрытия
  
  f.Reset;
  writeln($'Read#1: {f.Read}'); // r1(123,123.456)
  writeln($'Pos#1: {f.Pos}'); // 1, потому что мы открыли файл через ".Reset" (курсор в начале файла) и затем прочитали 1 элемент
  
  // В отличии от file of T, у BlockFileOf<T> нету режима чтения и режима записи
  // Они объеденены, поэтому не надо закрывать файл чтобы записать что-то после чтения
  f.Write(new r1(0,0));
  
  writeln($'Size#1: {f.Size}'); // 2, потому что r1(0,0) НЕ втиснуло между первыми 2 элементами, а записало поверх второго
  
  writeln($'EOF: {f.EOF}'); // True, потому что у нас всего было 2 элемента и курсор сейчас стоит на позиции 2 (1 чтение + 1 запись)
  
//  f.Seek(1);
  f.Pos := 1; // То же самое, что и .Seek(1), но лучше
  
  writeln($'Read#2: {f.Read}'); // r1(0,0), то, что мы только что записали
  
  f.Pos := 5; // Можно ставить за границей файла
//  f.Read; // Ошибка: Нельзя читать за пределами файла. Можно только записывать
  f.Write(new r1);
  writeln($'Size#2: {f.Size}'); // 6, потому что мы записали +1 элемент после позиции 5
  
  // Но вообще, размер правильно менять так:
  f.Size := 10;
  writeln($'Size#3: {f.Size}'); // 10
  writeln($'Pos#2: {f.Pos}'); // 6, как и была после того, как мы последний раз вызвали .Write
  
  // Программа сейчас завершится, поэтому файл закроется сам
  // Но если не вызвать хотя бы Flush, то изменения могут не сохранится
  f.Flush;
  
end.