Файловый тип состоит из линейной последовательности компонент любого типа, кроме файлового или структурного типа, который содержит компоненту файлового типа.
Файловый_тип::= "text" | ("file" "of" тип) | "file".
Файлы TEXT являются текстовыми файлами последовательного доступа. Их обработку можно вести только последовательно, строка, за строкой, слово за словом, символ за символом. Таким образом, если требуется считать строку из середины текстового файла, придется считывать все ей предшествующие. Однако этот недостаток с лихвой перекрывают возможности форматированного вывода и ввода информации произвольного типа из файла стандартными процедурами ввода-вывода. По сути дела, экран и клавиатура сами являются текстовыми файлами соответственно для записи и чтения. В модуле System содержатся 2 текстовые файловые переменные с именами Output и Input, первая из которых сопоставлена с экраном, а вторая - с клавиатурой.
Файлы file of тип являются типированными файлами прямого доступа. Это означает, во первых, что компоненты файла имеют один и тот же тип, а о вторых, что доступ к содержимому файла ведется произвольно, в любую позицию. Таким образом, например, если нам требуется записать в середину файла вещественных чисел новое число, мы легко можем произвести установку файловой позиции в требуемое местоположение и произвести запись.
Осторожнее с файлами file of string. Такое определение подразумевает, что для каждой строки будет резервироваться 256 байт внутри файла. Это очень неэффективный подход с точки зрения экономии дискового пространства. Лучше в такой ситуации, хотя и в ущерб скорости, воспользоваться текстовыми файлами.
Файлы file являются нетипированными файлами прямого доступа. У нетипированных файлов отсутствует заранее определенная структура. Запись и чтение для таких файлов производится блоками, состоящими из последовательностей байтов. Размер блоков задается при открытии файла.
Типированные и нетипированные файлы отличаются от текстовых тем, что информация в них хранится в том же формате, что и в оперативной памяти компьютера. Это означает, с одной стороны, значительно меньший размер по сравнению с текстовыми, а с другой - невозможность, в большинстве случаев, редактирования содержимого таких файлов с помощью любых текстовых редакторов. К счастью, ТП имеет достаточно средств для создания специальных программ просмотра и редактирования нетекстовых файлов.
Принципы работы с файлами
Общий принцип обработки содержимого файлов состоит в следующей последовательности действий:
1. Сопоставление файловой переменной и конкретного файла на диске.
2. Открытие файла.
3. Чтение из файла или (и) запись в файл.
4. Закрытие файла.
Рассмотрим стандартные процедуры, позволяющие реализовать принципы работы с файлами.
Сопоставление файлов |
procedure Assign(var f; name: string); |
Процедура Assign сопоставляет файловую переменную F конкретному файлу на диске с именем Name. |
Открытие файлов |
procedure Reset(var f); |
Процедура Reset открывает существующие текстовые файлы только для чтения, а типированные - для чтения и записи. F - файловая переменная, сопоставленная ранее с помощью процедуры Assign конкретному дисковому файлу. |
procedure Reset(var f:file[; recsize: Word]); |
Процедура Reset открывает существующий нетипированный файл F для чтения и записи. F - файловая переменная, сопоставленная ранее с помощью процедуры Assign конкретному дисковому файлу. Recsize - размер одной записи в файле. Если Recsize отсутствует, считается, что размер одной записи равен 128 байтам |
procedure Rewrite(var f); |
Процедура Rewrite создает текстовые файлы только для записи, а типированные - для чтения и записи. F - файловая переменная, сопоставленная ранее с помощью процедуры Assign конкретному дисковому файлу. Если файл с таким именем уже существовал на диске, он предварительно удаляется. |
procedure Rewrite(var f:file[; recsize: Word]); |
Процедура Rewrite создает нетипированный файл F для чтения и записи. F - файловая переменная, сопоставленная ранее с помощью процедуры Assign конкретному дисковому файлу. Recsize - размер одной записи в файле. Если Recsize отсутствует, считается, что размер одной записи равен 128 байтам. Если файл с таким именем уже существовал на диске, он предварительно удаляется. |
procedure Append (var f:text); |
Процедура Append открывает текстовый файл F для добавления в него информацией. F - файловая переменная, сопоставленная ранее с помощью процедуры Assign конкретному дисковому файлу. |
Чтение и запись файлов |
Для доступа к содержимому текстовых файлов используются процедуры Read, Readln, Write, Writeln, причем первым параметром передается имя файловой переменной. Методы обработки текстовых файлов с помощью этих процедур ничем не отличаются от методов обработки клавиатуры и экрана. Для доступа к содержимому типированных файлов используются процедуры Read и Write, причем первым параметром также передается имя файловой переменной. Тип записываемых или считываемых переменных не должен отличаться от типа сохраненной в файле информации. В качестве параметров процедуры Write запрещено использовать выражения. |
procedure BlockRead(var f: file; var Buf; Count: Word [; var Result: Word]) |
Процедура BlockRead читает в переменную Buf Count записей из файла F (размер каждой записи определен при открытии файла). В переменной Result возвращается число действительно прочитанных записей. |
procedure BlockWrite(var f: file; var Buf; Count: Word [; var Result: Word]) |
Процедура BlockWrite Записывает в файл F Count записей из переменной Buf. В переменной Result возвращается число действительно сохраненных записей. Процедуры BlockWrite и BlockRead не могут обрабатывать более 64 килобайт информации за один раз. |
Закрытие файла |
procedure Close(var f); |
Процедура Close закрывает файл F. Закрытие файлов требуется для освобождения всех файловых буферов в оперативной памяти, а также ресурсов, затребованных у операционной системы при открытии файла. По завершении работы программы все незакрытые файлы автоматически закрываются. |
Задача 38. Написать две программы. С помощью первой из них создать и заполнить типированный файл десятью целыми числами. Вторую использовать для просмотра содержимого файла, сформированного первой программой.
Решение:
{-----------первая программа------------}
var f:file of integer;
i,v:integer;
s:string;
begin
write('Введите имя файла:'); readln(s);
Assign(f,s); Rewrite(f); {сопоставляем файловую переменную и создаем текстовый файл}
writeln('Эти значения будут сохранены в файле:');
for i:=1 to 10 do begin {заполняем файл}
v:=random(101)-50; {получаем случайное значение из промежутка
[-50,50]}
write(f,v); {сохраняем полученное число в файле ...}
write(v:4);{... а также выводим его на экран}
end; {файл заполнен}
writeln;
close(f);{закрываем файл}
readln;
end.
{-----------вторая программа------------}
var f:file of integer;
i,v:integer;
s:string;
begin
write('Введите имя файла:'); readln(s);
Assign(f,s); Reset(f); {сопоставляем файловую переменную и открываем текстовый файл для чтения}
write('Содержимое файла ',s,': ');
for i:=1 to 10 do begin {считываем содержимое файла}
Read(f,v);{считываем очередное число из файла}
write(v:4);{выводим полученное значение на экран}
end;{содержимое файла прочитано}
writeln;
close(f);{закрываем файл}
readln;
end.
Задача 39. Написать две программы. С помощью первой из них создать и заполнить типированный файл (file of byte) размером в 100000 байт. С помощью второй создать аналогичного размера нетипированный файл. Сравнить скорости работы обеих программ.
Решение:
{-----------первая программа------------}
var f:file of byte;
i:longint;
b:byte;
s:string;
begin
write('Введите имя файла:'); readln(s);
Assign(f,s); Rewrite(f);{сопоставляем и открываем типированный файл для записи}
for i:=1 to 100000 do write(f,b);{сохраняем 100000 байт в файле}
close(f);{закрываем файл}
writeln('Файл сохранен');
readln;
end.
{-----------вторая программа------------}
var f:file;
b:array [1..50000] of byte;
s:string;
begin
write('Введите имя файла:'); readln(s);
Assign(f,s); Rewrite(f,1); {сопоставляем и открываем нетипированный файл для записи, устанавливая размер одной записи в 1 байт}
BlockWrite(f,b,50000);{сохраняем первую половину требуемого содержимого файла}
BlockWrite(f,b,50000);{сохраняем вторую половину требуемого содержимого файла}
close(f);
writeln('Файл сохранен');
readln;
end.
Первая программа на компьютере с процессором Pentium-120 выполняется около 20 секунд, вторая - практически мгновенно. Выводы сделайте сами.
После выполнения программ вы наверняка заметите, что размер первого (типированного) файла постоянен и равен 200 байт (100 значений типа Integer умножить на 2 байта памяти для каждого числа), в то время как размер текстового файла изменяется от запуска к запуску второй программы и превышает размер первого файла по крайней мере в полтора раза.