Нетипизированные файлы в Pascal
В Pascal, кроме рассмотренных, существуют также нетипизированные файлы. Они совместимы со всеми типами файлов и используются тогда, когда тип элементов файла не важен, например при копировании. Такие файлы описываются следующим образом:
var имя_переменной: File;
Файл без типа представляется как последовательность элементов произвольного типа, но оговоренного размера. Это значит, что в файл можно записать значение любой переменной, имеющей заданный размер, а при чтении из такого файла допускается произвольная интерпретация содержимого очередного элемента.
Открываются файлы без типа теми же операторами reset и rewrite, но в этом случае имеется второй параметр — размер записи (элемента файла), заданный в байтах. Предварительно нужно с помощью оператора assign связать внутреннее имя файла с внешним:
assign(f, 'data.dat'); reset(f, 1);
Второй параметр операторов reset и rewrite может быть опущен, что означает задание размера записи в 128 байт. Наибольшая скорость обмена данными обеспечивается при длине записи, кратной 512 байт (размеру сектора на диске).
Следует помнить, что если общий размер файла не кратен выбранном размеру записи, то последняя запись окажется неполной, и файл может быть прочитан не до конца. Этого не будет, если задать размер записи равным одному байту.
Обмен данными при работе с нетипизированными файлами осуществляется с участием рабочего буфера. Для него в программе определяется отдельная переменная. Ее размер должен быть достаточным для размещения данных, которые читаются/записываются за один сеанс чтения/записи.
Чтение из нетипизированного файла осуществляется процедурой blockread.
blockread(файловая_переменная, переменная_буфер, количество_записей);
Ее третий параметр — это количество записей, читаемых за один раз; имеет тип Word.
При выполнении процедуры blockread данные помещаются в оперативную память, начиная с первого байта переменной, указанной в качестве второго параметра. Поэтому переменная_буфер должна иметь размер, равный произведению, количества читаемых за один раз записей (третий параметр) и размера записи, заданного в процедуре reset. В blockread возможно задание четвертого параметра (тип Word), в который помещается число фактически прочитанных записей.
Запись данных в нетипизированный файл производится только после его открытия с помощью процедуры rewrite. Для записи используется процедура blockwrite, которая имеет такие же три или четыре параметра, как и blockread. При этом в переменную_буфер нужно предварительно поместить записи. Количество этих записей должно совпадать со значением третьего параметра процедуры blockwrite, а размер — со вторым параметром процедуры rewrite. В четвертом, если он имеется, параметре blockwrite возвращается количество фактически помещенных в фал записей. Если на диске нет свободного места, то после выполнения процедуры blockwrite значения третьего и четвертого параметров будут отличаться.
Если при чтении с диска окажется, что размер буфера будет меньше указанного выше, или при записи на диск недостаточно свободного места, то при отсутствии четвертого параметра в процедурах blockread и blockwrite будет зафиксирована ошибка. При наличии четвертого параметра ошибка не будет сгенерирована.
Работа с нетипизированными файлами на примере копирования файла:
const COUNT = 512; // размер буфера // Кол-во читаемых записей при длине записи в 1 байт. var fileIn, fileOut: File; name1, name2: String; numRead, numWrite: Word; // фактич. считанные/записанные записи buf: array[1..COUNT] of Char; // буфер begin write('Исходный файл: '); readln(name1); assign(fileIn, name1); {$I-}reset(fileIn, 1);{$I+} if IOResult <> 0 then begin writeLn('Файл-оригинал не найден'); halt end; write('Имя копии: '); readln(name2); assign(fileOut, name2); rewrite(fileOut, 1); // длина записи 1 байт repeat blockread(fileIn, buf, COUNT, numRead); blockwrite(fileOut, buf, COUNT, numWrite); until (numRead = 0) or (numWrite <> numRead); writeln('Копирование завершено'); if numRead <> numWrite then writeln('Размеры файлов не равны'); close(fileOut); close(fileIn); end.
Пример выполнения программы:
Исходный файл: flag.png Имя копии: colors.png Копирование завершено Размеры файлов не равны