Главная » Free Pascal » Работа с нетипизированными файлами Free Pascal

0

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

отсутствует распределение по полям заданных типов. Для обмена с двоичным фай- лом используются специальные процедуры BlockRead и BlockWrite:

BlockRead(vf, buf, n_BLK[, N]); BlockWrite(vf, buf, n_BLK[, N]);

Здесь:

± buf — имя переменной (обычно массив типа byte), играющий роль буфера в оперативной памяти;

± n_BLK — количество блоков, участвующих в обмене;

± N —  имя  переменной,  в  которую  заносится  количество  блоков,  фактически принявших участие в обмене.

По умолчанию при открытии двоичных файлов устанавливается длина блока, равная 128 байтам. Однако пользователь может заказать любую другую длину, ко- торую он считает более удобной для своей программы:

Reset(vf, 80);

Rewrite(vf, 512);

Четвертый параметр в операторах обмена не является обязательным. Но он мо- жет оказаться полезным по ряду причин. При записи на диск может оказаться, что свободного места на диске не хватает для размещения указанного числа блоков. При чтении из файла может возникнуть ситуация, когда общее количество блоков в файле не кратно количеству блоков, указанных в операторе BlockRead. И тогда по- следняя считываемая порция данных будет содержать меньшее количество блоков.

Двоичные файлы наряду с последовательным обменом поддерживают и прямой доступ к блокам, которые подобно записям в типизированных файлах нумеруются с 0. Для перехода к блоку с указанным номером используется процедура Seek: Seek(vf, num_BLK);

Опрос номера текущего доступного блока производится с помощью функции FilePos. Для определения общего количества блоков в файле можно воспользо- ваться функцией FileSize.

В процессе работы с двоичным файлом с помощью процедуры Truncate (vf)

можно выполнить так называемое усечение данных. При этом головная часть файла до текущего блока сохраняется, а хвостовые данные удаляются.

В листинге 10.6 приводится пример копирования файла. Независимо от струк- туры данных, хранящихся в копируемом файле, он рассматривается как двоичный. На самом деле, способ организации данных в файле и специфика их обработки оп- ределяются программистом. В нашем случае необходимо скопировать содержимое файла байт в байт, независимо от того, что в каждом байте находится. В первую очередь, этим обстоятельством диктуется выбор размера блока, равный одному байту. Кроме того, такая длина блока позволяет не задумываться над количеством блоков, хранящихся в файле. На каждом шаге чтения из исходного файла мы за- прашиваем некоторое количество блоков и переписываем в копию ровно столько блоков, сколько удалось прочитать. Равенство нулю этой величины фиксирует ко- нец операции копирования.

   Листинг 1 0 .6 .  Программа  к опиро вания  ф а йл а  copy_file                          

program copy_file; const

n_buf=30000; {размер буфера обмена} var

buf: array [1..n_buf] of byte; vf_in, vf_out: file;

num_in, num_out: integer;

begin

assign(vf_in,’5.txt’); reset(vf_in,1); assign(vf_out,’6.bin’); rewrite(vf_out,1); repeat

blockread(vf_in,buf,n_buf,num_in); dlockwrite(vf_out,buf,num_in,num_out);

until (num_in = 0)or(num_in <> num_out); close(vf_in);

close(vf_out);

end.

В ранних версиях систем Turbo Pascal, функционировавших под управлением MS-DOS, придавалось большое значение объему порции данных, участвовавших в обмене. Системное ограничение сверху (32 767) позволяло за один присест прочи- тать максимальное количество подряд идущих секторов на диске — кластер. Это обеспечивало оптимальную скорость обмена. С увеличением объема винчестеров и ростом размера кластеров за оптимизацией обмена следит электроника, управляю- щая работой винчестера. Поэтому задание в программе размера порции данных, считываемых за один присест, особой роли не играет.

Еще одна логическая проверка (num_in <> num_out) в завершающей строке цикла repeat связана с возможным переполнением диска.

Программа reserve демонстрирует еще одну операцию, характерную для многих редакторов — создание резервной копии файла с расширением bak (листинг 10.7).

   Листинг  1 0 .7 . Программа  с озд а ния  ре зе рвной  к опии  ф а йл а  reserve                

program reserve; uses SysUtils; const

N = 32767;

var

f1, f2: file;

rd, wr: integer;

buf: array [1..N] of byte; name1, name2: string;

begin

if ParamCount=0 then begin

writeln(‘Must be: reserve file’); readln; exit;

end; name1:=ParamStr(1); assign(f1,name1);

{$I-} reset(f1,1); {$I+} if IOresult <> 0 then

begin

writeln(‘File ‘,name1,’ not found’); readln; exit;

end; name2:=ChangeFileExt(name1,’.BAK’); assign(f2,name2);

rewrite(f2,1);

repeat

blockread(f1,buf,N,rd); blockwrite(f2,buf,rd,wr);

until(rd=0)or(rd <> wr); close(f1);

close(f2); end.

Для запуска этой программы в командной строке должно быть задано имя фай- ла, для которого создается резервная копия. Имя файла с резервной копией форми- руется с помощью системной функции ChangeFileExt. Заполнение файла с резерв- ной копией выполняется по схеме, описанной в предыдущем примере.

Тесная связь между типизированными и нетипизированными файлами подчер- кивается программой bin_rec (листинг 10.8). Она выполняет точно такие же дейст- вия, как и программа rec_file. Работа с полями записи здесь моделируется с по- мощью указателей.

   Листинг 1 0 .8 .  Программа  bin_rec                                             

program bin_rec; var

buf: array [1..17] of byte; f1: file;

p: pointer;

ps: ^string; pi: ^integer; pd: ^double; j: integer;

begin

assign(f1,’7.bin’);

p:=@buf[1]; ps:=p;

p:=@buf[6]; pi:=p;

p:=@buf[10]; pd:=p; rewrite(f1,17); for j:=1 to 10 do

begin

pi^:=j; pd^:=sqrt(j);

blockwrite(f1,buf,1); writeln(ps^,pi^:4,pd^:10:4);

end;

close(f1); writeln; reset(f1,17);

for j:=9 downto 0 do begin

seek(f1,j); blockread(f1,buf,1); writeln(ps^,pi^:4,pd^:10:4);

end; close(f1); readln;

end.

Источник: Кетков, Ю. Л., Свободное программное обеспечение. FREE PASCAL для студентов и школьников, Ю. Л. Кетков, А. Ю. Кетков. — СПб.: БХВ-Петербург, 2011. — 384 с.: ил. + CD-ROM — (ИиИКТ)

По теме:

  • Комментарии