Операции над типизированными файлами в Турбо Паскале

Типизированные файлы называются таковыми потому, что для них определён тип данных записи. В них все записи являются одного типа (иными словами, однородными), т.е. file of тип_данных. Такие файлы содержат информацию в бинарном виде и (нормальный) человек прочесть их не сможет. Типом данных может быть любой тип данных Паскаля за исключением типа file.

Рассмотрим на примере тип запись (record). Тип запись определяется заранее (уже известен).

Например:

type
    TInfoRecord = record  { Определяем тип записи TInfoRecord }
        Num:  integer;     { порядковый номер, числовой тип integer }
        Name: string[20];  { Имя, до 20 символов }
        Tel:  string[12];  { Телефон, до 12 символов }
    end;

Позиция при открытии (существующего) файла:

*01234

В файле может ещё не быть записей, если он едва был создан.

Не забывайте, что нумерация записей начинается с нуля.

Поиск записи

Алгоритм:

  1. установить позицию на начало, если необходимо (не нужно когда только что открыли файл для чтения)
  2. проверять каждую запись по нужному критерию (имя, телефон и т.д.)
  3. продолжать с пункта 2 пока не конец файла.
Пока не конец файла
  Считать запись
  Проверить, искомая ли. Если да, то что-то делать (вывести на экран, к примеру).
конец цикла

Добавление записи

Чтобы добавить запись в файл, необходимо сначала установить позицию в конец файла командой Seek ,а затем производить запись с помощью Write.

Позиция в конце файла

01234*

Производим запись. Теперь добавилась ещё одна.

012345*
type
  TStudentInfo = record
    Name: string[30];
    group: string[10];
    Exams: array[1..5] of byte;
  end;
 
var
  F: file of TStudentInfo;
  st: TStudentInfo;
  i: integer;
begin
     Assign (f, 'students.dat');
     {$I-}
     Reset (F); { попытка открыть файл }
     {$I+}
 
     if IOresult <> 0 then { при неудаче создаём пустой файл }
          Rewrite (F);
 
     Seek (F, FileSize (F)); { становимся в конец файла }
 
     With st do { заполняем данные записи }
     begin
          write ('Имя студента: '); readln (Name);
          write ('Группа: '); readln (group);
          writeln ('Оценки по пяти экзаменам:');
          for i := 1 to 5 do
               readln (Exams[i]);
     end;
 
     Write (F, st); { записываем запись в файл }
 
     Close (F);
end.

Правка записи

Чтобы поправить N-ю запись, надо стать на позицию этой записи с помощью Seek (F, recN), а затем производить запись. Аналогично предыдущему примеру, только вместо Seek (F, FileSize(F)) пишем Seek (F, recN). При этом надо следить за тем, чтобы не возникло ошибки при введении несуществуещего номера записи, чтобы программа не завершилась с ошибкой.

01*23

Здесь курсор установлен на позиции 2, готовой для чтения и правки записи под номером 2.

После того, как изменили запись, позиция продвинулась вперёд.

type
  TStudentInfo = record
    Name: string[30];
    group: string[10];
    Exams: array[1..5] of byte;
  end;
 
var
  F: file of TStudentInfo;
  st: TStudentInfo;
  recN, i, MaxRecords: integer;
  exists: boolean;
begin
     Assign (f, 'students.dat');
     {$I-}
     Reset (F);
     {$I+}
 
     if IOresult <> 0 then
          halt;
 
     MaxRecords := FileSize(F);
     if MaxRecords = 0 then
     begin
          writeln ('Записей нет!');
          exit;
     end;
 
     repeat
          write ('Введите номер записи для замены [0..', MaxRecords-1, ']: ');
          readln (recN);
          {$I-}
          Seek (F, recN); { пытаемся установиться на нужную запись }
          {$I+}
          exists := (IOresult = 0) and (recN < MaxRecords); { признак успеха }
          if Not exists then
               writeln ('Вы ввели номер несуществующей записи! Попытайтесь снова.');
     until exists;
 
     With st do
     begin
          write ('Имя студента: '); readln (Name);
          write ('Группа: '); readln (group);
          writeln ('Введите оценки по 5 экзаменам:');
          for i := 1 to 5 do
               readln (Exams[i]);
     end;
 
     Write (F, st); { записываем запись в файл }
 
     Close (F);
end.

Поиск и правка записи

Если надо найти запись и исправить ее, надо:

  1. установить позицию на начало, если необходимо (не надо когда только открыли файл для чтения)
  2. проверять каждую запись по нужному критерию (имя, телефон и т.д.)
  3. вернуться на одну позицию назад:
    Seek(F,FilePos(F)-1), т.к. после чтения записи с файла позиция уже продвинулась на следующую;
  4. внести изменения в записи и затем производить запись в файл.
  5. продолжать с пункта 2 пока не конец файла.
type
  TStudentInfo=record
    Name: string[30];
    Kurs: string[20];
    Exams: array[1..5] of byte;
  end;
 
var
  f: file of TStudentInfo;
  st: TStudentInfo;
  who: string[30];
  found: boolean;
begin
     write('Кого ищем? ');
     readln(who);
     if who='' then exit;
 
     assign(f,'students.dat');
     {$I-}
     reset(F);
     {$I+}
     found:=false;
     if IOresult=0 then
     with st do
     while Not EOF(F) do
     begin
          read(F,st);
          if name=who then  { нашли такого/ую }
          begin
               write('Заменить на фамилию: ');
               readln(name);
               found:=true; 
               seek(F,FilePos(F)-1); { вернуться на 1 позицию обратно, т.е. на позицию того, что надо заменять }
               write(f,st);
               break; { убрать это, если известно, что таких несколько }
          end;
     end;
     close(f);
     if Not Found
        then writeln(Who,' не найден. Ха-ха')
        else writeln(Who,' найден и заменен.');
     writeln(#13#10'Жми Enter');
     readln;
end.

Удаление записи

Удаление последовательности записей

Для удаления (отсечения) последовательности записей, начиная с текущей позиции (можно установить с Seek), применяют процедуру Truncate.

Процедура Truncate( var f )  устанавливает в текущей позиции признак конца файла
и удаляет (стирает) все последующие блоки.

Удаление одной записи

Для удаления одной неконечной записи требуется воспользоваться созданием дополнительного файла, в который запишутся все записи, кроме заданной.

Записываем записи 0..i-1, пропускаем запись i, а потом дописываем записи i+1..N.

Другой способ (хитрый)

Скопировать последнюю запись на место i-й, а потом отсечь последнюю с помощью Truncate.

Вставка записи

Для вставки записи также требуется воспользоваться созданием дополнительного файла, в который запишутся все записи:

  • сначала записи 1..i-1
  • затем вставляемая запись
  • затем записи i, .. N
 
pascal/files/typed.txt · Последние изменения: 2010/05/27 15:03 От romtek
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki