Лекция 9_2. Синтаксис описания файлов и обращения к ним.
Описание файлов
Типизированные файлы.
Описание типа:
type <имя типа> = file of <тип компонентов (ЗАПИСЕЙ);> Этот тип можно назвать базовым типом для файла.
Например:
type dbfil = file of double; ar1 = array [1..20] of Integer;
fiar = file of ar1;
Описание файловых переменных:
var <имя переменной> = <имя типа (файлового)>; Например:
db1: dbfil; db2: file of double;
Нетипизированные файлы.
Описание типа:
type <имя типа> = file; Например:
type nf = file;
Описание файловых переменных:
var <имя переменной> = <имя типа (файлового)>; Например:
fff: nf; fara: file;
Текстовые файлы.
Описание типа:
type <имя типа> = Text; (В Делфи: <имя типа> = TextFile)
Например:
type tx1 = Text;
Описание файловых переменных:
var <имя переменной> = <имя типа (файлового)>; Например:
tfu: tx1; ftx: text;
Связывание имени файла с файловой переменной
То есть мы должны объявить, что такому-то идентификатору (файловой переменной) соответствует имя файла на диске (включая устройство и путь). Для этого используется процедура Assign (в Делфи - AssignFile).
Синтаксис:
Assign(<файловая переменная, т е идентификатор>,<выражение строкового типа>);
Примеры:
Assign(tfu,'MyFile.txt'); Assign(fff,'.\dano.dat'); Assign(fara,'..\ff\ras2.dat');
Assign(fara,'D:\copy6\ras2.dat');
Процедура Assign применяется одинаково ко всем файловым типам. Если при вызове Assign для текстового файла не указана файловая переменная, то подразумеваются стандартные переменные: Input - клавиатура и Output - экран. Если вызывать read, readln или write, writeln без указания файловой переменной, также ввод будет с клавиатуры, а вывод - на экран.
Начало работы с файлом.
Чтобы начать работу с файлом, нужно вызвать процедуру reset или rewrite.
Синтаксис:
Типизированные и текстовые файлы:
Reset(<файловая переменная>); Пример: reset(db2);
Открывается СУЩЕСТВУЮЩИЙ файл, который соединен с этой переменной процедурой Assign. Файловый указатель ставится на начало файла (позиция = 0). ( После чего
файл готов к чтению/записи первой записи).
ReWrite(<файловая переменная>) Пример: rewrite(db2);
Открывается новый пустой файл и ему присваивается имя, заданное в процедуре Assign.
Если файл с таким именем уже существует, он очищается. Файловый указатель ставится на начало файла (позиция = 0). ( После чего файл готов к записи первой записи, а после появления записей - к их чтению. При этом переставить файловый указатель можно либо процедурой reset, либо процедурой seek, описанной далее).
Дополнительно - текстовые файлы можно открыть для добавления данных в конец файла:
Append(<файловая переменная>); Например: Append(ftx);
Удобно при налаживании программы выводить данные, используя пары: close; append;
<записать порцию данных> close; append; <записать порцию данных>... и т д
Если убрать close, то нет гарантии, что все данные, которые "записаны" останутся в файле на диске.
Нетипизированные файлы.
Reset(<файловая переменная>,[<размер записи>]); Пример: reset(fara,512);
Примечания:
1. Если размер записи не указан, подразумевается 128 байт (по умолчанию).
2. Обычно размер записи равен размеру кластера на устройстве (для дискет - 512 байт) или 1 байт.
ReWrite(<файловая переменная>,[<размер записи>]); Пример: rewrite(fara,512);
Примечания - те же, что для reset.
Чтение из файла
Типизированные файлы
Процедура Read(<файловая переменная>,<переменная - буфер чтения>, <переменная - буфер чтения>,...);
Переменные должны быть объявлены как переменные того же типа, что и базовый тип файла.
Исполнение этой процедуры:
- Байты файла, начиная от текущего положения файлового указателя, в количестве, соответствующем произведению длины базового типа на количество переменных копируются в переменные.
- Файловый указатель перемещается на это же количество байт вперед, к началу соответствущей записи.
Ясно, что для чтения файла процедуру Read нужно исполнить многократно, обычно - в цикле. Для избежания аварии нужно каждый раз проверять - не стоит ли указатель на конце файла. Для этого есть функция eof(<файловая переменная>). Это - булевская функция. Она возвращает true, если файловый указатель находится в конце файла, т е дальше последнего байта файла и возвращает false - иначе.
Пример программы.
Убедимся, что файл, открытый процедурой rewrite
можно читать.
var f1: file of double; buf: double; ii: byte;
begin
Assign(f1, 'myfile.dub'); rewrite(f1);
for ii:= 1 to 9 do
begin buf:= 10*ii+ii/10;
write(f1,buf);
end;
seek(f1,4);
for ii:= 1 to 5 do
begin buf:= 77.7;
write(f1,buf);
end;
close(f1);
reset(f1);
while not eof(f1) do
begin
read(f1,buf);
writeln(buf);
end;
close(f1);
end.
(Файл MyFILE.DUB появился в той же папке, где
находится turbo.exe, а при запуске откомпилированного
файла, т е FILE1.EXE файл MyFILE.DUB появился
в той же папке, где находится FILE1.EXE. В обоих
случаях - в текущей папке)
---- Результат: -----
1.01000000000000E+0001
2.02000000000000E+0001
3.03000000000000E+0001
4.04000000000000E+0001
7.77000000000000E+0001
7.77000000000000E+0001
7.77000000000000E+0001
7.77000000000000E+0001
7.77000000000000E+0001
Текстовые файлы
Параметры-переменные, которые заполняются данными при помощи процедур read/readln из текстовых файлов, могут иметь типы: char, string, PChar, численные типы (целые и вещественные). Аналогично, процедуры write/writeln записывают из параметров- выражений этих же типов и boolean (в виде true или false).
Процедура read имеет синтаксис:
read ([<файловая переменная>,]<переменная-буфер>, <переменная-буфер>,...);
При этом данные (численные), записанные в файле, должны отделяться друг от друга пробелом или знаком табуляции, так что очередная порция данных между разделителями сохраняется в очередной переменной из списка параметров. Переменная-буфер должна иметь тип - один из численных.
Если переменная-буфер имеет тип char, то данные в файле читаются посимвольно в соответствующие переменные.
Если переменная-буфер имеет тип string[N], то данные в файле читаются по N символов в соответствующие переменные, в частности, string - читается 255 символов.
Если в файле встретится новая строка (#13#10) чтение данных из файла прекратится.
Процедура readln делает то же самое, но способна читать признак конца строки (#13#10) и переходить к чтению следующей строки файла.
Нетипизированные файлы
Чтение производит процедура BlockRead, которая имеет синтаксис:
BlockRead(<файловая переменная>,<переменная - буфер чтения>, N [, fact]);
где: N - (выражение) - сколько записей нужно прочесть,
переменная - буфер должна имет размер не менее, чем N*<размер записи>
необязательный параметр fact возвращает число фактически прочитанных записей ( если достигнут конец файла и прочтено < N записей.)
Запись в файл.
Типизированные файлы
Процедура Write(<файловая переменная>,<переменная - буфер записи>, <переменная - буфер записи>,...);
Переменные должны иметь тип - базовый тип файла.
Исполнение этой процедуры:
- Содержимое переменных записывается в файл, начиная от текущего положения файлового указателя.
- Файловый указатель перемещается на соответствующее число байт вперед.
Текстовые файлы
Процедура write имеет синтаксис:
write ([<файловая переменная>,]<выражение>, <выражение>,...);
Значения выражений (тип: строковый, символьный, PChar, целый, вещественный, логический) записываются в файл по порядку.
Нетипизированные файлы
Запись производит процедура BlockWrite, которая имеет синтаксис:
BlockWrite(<файловая переменная>,<переменная - буфер записи>, N [, fact]);
где: N - (выражение) - сколько записей нужно прочесть,
переменная - буфер должна имет размер не менее, чем N*<размер записи>
необязательный параметр fact возвращает число фактически записанных записей.
Примеры 1, 2:
Использование текстовых файлов.
Примеры 3-5:
Использование текстовых файлов.
Примеры 6-8:
Использование нетипизированного файла.
Примечание:
В Делфи для работы с файлами можно применять класс TFileStream, а также описанные
выше средства Turbo - Pascal7, однако вместо Assign -> AssignFile, Close -> CloseFile,
Text -> TextFile. Удобно также пользоваться методами .SaveToFile класса TStrings (компонеты Memo,ListBox и др.).