Описание и структура типизированного файла
Описание файловой переменной:
var F :file of тип_компонентов,
где тип_компонентов не может быть файловым, не может быть динамической структурой. Т.е. при описании типа компонентов должен быть известен размер компонента в байтах.
Например:
type Matrix=array[1..10,1..15] of real;
Person=record
FIO:string[20];
group:1..12
end;
var FI: file of integer; //файл из целых чисел
FM: file of Matrix; //файл из двумерных массивов
FP: file of Person; //файл из записей
Cтруктура типизированного файла:
компонент | компонент | . . . | компонент | Eof |
Типизированные файлы напоминают массивы: все компоненты файла одного и того же типа, каждый компонент имеет номер, который используется для прямого доступа к этому компоненту. Нумерация начинается с 0.
Особенности типизированных файлов
1) Типизированные файлы - двоичные, т.е. содержат машинное представление данных, поэтому они не могут быть созданы, в отличие от текстовых файлов, с помощью программы-редактора.
2) Типизированный файл можно одновременно и читать, и писать. Процедуры Reset и Rewrite открывают файл и на чтение, и на запись, устанавливая файловый указатель на 0-ой компонент.
Дополнительные подпрограммы для организации прямого доступа
Текущая позицию файлового указателя
function FilePos(F): int64
Возвращает текущую позицию файлового указателя.
- После открытия файла FilePos(F)=0
- После завершения чтения всего файла FilePos(F)=FileSize(F)
Количество компонентов файла
function FileSize(F): int64
Возвращает количество компонентов файла.
Установка файлового указателя
procedure Seek(F, n)
Устанавливает файловый указатель на компонент с номером n.
- Установка на начало файла: Seek(F,0)
- Установка на последний компонент: Seek(F,FileSize(F)-1)
Усечение файла
procedure Truncate(F)
Усекает файл, отбрасывая компоненты с позиции файлового указателя до конца файла.
Удаление всех компонентов: Seek(F,0); Truncate(F) или проще: Rewrite(F).
Типичные задачи для типизированных файлов
Дан файл целых чисел:
var F:File of integer; x:integer;
Чтение файла от начала до конца
Вариант 1
Reset(F);
while not Eof(F) do Read(F,x); //Пока не наступит конец файла
//Номер прочитанного компонента равен FilePos(F)-1
Вариант 2
Reset(F);
for i:=0 to Filesize(F)-1 do Read(F,x) //Для всех компонентов файла
//Номер прочитанного компонента равен i.
Чтение файла в обратном порядке (с конца до начала)
Reset(F);
for i:=Filesize(F)-1 downto 0 do //Для всех компонентов файла с номером i от последнего до 0-го
begin Seek(F,i); Read(F,x) end
Замена только что прочитанного компонента файла на новый компонент
Reset(F);
while not Eof(F) do
begin Read(F,x);
if (x надо заменить на xnew) then
begin Seek(FilePos(F)-1); //Возврат на позицию, откуда был прочитан x
write(F,xnew) //Запись нового компонента
end
end
Удаление компонента из типизированного файла
Вариант 1. Найти в файле удаляемый компонент, скопировать следующие за ним компоненты на одну позицию ближе к началу файла, затем удалить последний компонент/
for i:=p+1 to Filesize(F)-1 do //p – номер удаляемого компонента
begin
Seek(F,i);
read(F,x);
Seek(F,i-1);
write(F,x);
end;
Truncate(F); //Удаление последнего компонента
Вариант 2. Переписать в новый файл все компоненты, кроме удаляемого.
Rewrite(Fnew); //Открытие нового файла
Seek(F,p); //p – номер удаляемого компонента
while not Eof(F) do
begin
read(F,x);
if (FilePos(F)-1)<>p
then write(Fnew,x);
end;
Вариант 3. На место удаляемого компонента записать последний компонент файла, затем последний удалить. Преимущество – малое число операций. Недостаток – нарушается порядок компонентов файла.
Seek(F,Filesize(F)-1); //Установка указателя на последний компонент
Read(F,y); //Чтение последнего компонента
Seek(F,p); //p – номер удаляемого компонента
write(F,y);
Seek(F,Filesize(F)-1);
Truncate(F); //Удаление последнего компонента