На этом шаге мы рассмотрим средства работы с типозированными файлами.
Все элементы типизированного файла должны быть одного типа. Они могут быть любого типа, кроме файлового, а таже типов "запись" и "класс", которые включают поля файлового типа как составную часть.
Пример недопустимых объявлений:
type TF1 = file of file; TFR = record A: Integer; F: file of Real; end; var TF2 : file of TFR;
Типизированные файлы допускают как последовательный, так и прямой доступ. Работая с прямым доступом, следует помнить, что элементы типизированных файлов всегда нумеруются, начиная от нуля.
Рассмотрим некоторые процедуры и функции, используемые для работы с типизированными файлами.
Чтение из типизирированных файлов выполняется только процедурой Read, а запись - только процедурой Write. При этом единицей чтения/записи может быть только переменная того же типа, что и тип файла.
Процедура Read для типизированных файлов имеет следующий формат:
Read (<имя файловой переменной>, <список переменных>);
При считывании в каждую переменную из списка процедуры Read, указатель текущей позиции в файле перемещается на следующий элемент. Если указатель текущей позиции файла находится за последним элементом, то есть в конце файла (Eof(f) = True), то выполнение процедуры Read приводит к ошибке времени выполнения.
Процедура Write для типизированных файлов имеет такой формат:
Write (<имя файловой переменной>, <список переменных>);
Выполняя запись в файл следует помнить, что при записи каждой переменной указатель текущей позиции в файле, также как и при чтении, перемещается на следующий элемент. Если указатель текущей позиции файла находится за последним элементом, то есть в конце файла (Eof(f) = True), то при выполнении процедуры Write файл расширяется. Для работы с прямым доступом предназначены следующие процедуры и функции:
В качестве примера организации прямого доступа к элементам типизированного файла рассмотрим программу сортировки файла методом "пузырька".
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Label1: TLabel; Label2: TLabel; Button1: TButton; Memo2: TMemo; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var f : file of Integer; X, Y : Integer; i, j : Longint; S : string; begin {$I-} AssignFile (f, 'Sort.Dat'); Reset(f); {$I+} if IOResult <> 0 then begin MessageDlg('Ошибка открытия файла',mtError,[mbOK], 0); Halt(1); end; { ---------------------------------------} for i := 0 to FileSize(f)-1 do begin Read(f, X); Str(X:15,S); Memo1.Lines.Add(S); end; CloseFile (f); { ---------------------------------------} Reset ( f ); for i:=FileSize(f)-1 downto 1 do { "Всплывание" очередного максимального элемента { на i-ю позицию } for j := 0 to i-1 do begin Seek ( f, j ); Read ( f, X, Y ); if X > Y then begin Seek ( f, j ); Write ( f, Y, X ); end; end; CloseFile (f); { ---------------------------------------} Reset(f); for i :=0 to FileSize(f)-1 do begin Read(f,X); Str(X:15,S) ; Memo2.Lines.Add(S); end; CloseFile(f); end; procedure TForm1.FormCreate(Sender: TObject); var f : file of Integer; X,i : Integer; begin { Создание файла. } randomize; AssignFile (f, 'Sort.Dat'); Rewrite(f); for i:=1 to 20 do begin X := random(40); Write(f,X); end; CloseFile (f); end; end.
При выполнении проекта, использующего приведенный модуль, будет получен следующий результат:
Рис.1. Результат работы приложения
Напомним, что тип типизированного файла представляет собой "шаблон" ("окно"), который мы "накладываем" на физический файл для доступа к его элементам. Но если это так, то возникает вопрос: "А можно ли создать файл, используя один "шаблон", а прочитать его, используя другой?" Действительно, такое возможно. Например, в следующем модуле в файл типа Char сначала записывается ряд символов, а затем этот же физический файл открывается как файл типа Byte и, в результате, на печать выводятся коды ASCII, записанных в него символов:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Label1: TLabel; Label2: TLabel; Edit1: TEdit; Edit2: TEdit; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); const TestStr : string ='0123456789ABCDEFGHIJ'; var FC : file of Char; FB : file of Byte; B,i: Byte; S,Res : string; begin AssignFile (FC, 'Test.Dat' ); Rewrite ( FC ) ; Res:=''; for i:=1 to 20 do begin Write ( FC, TestStr[i] ); Res:=Res + ' ' + TestStr[i]; end; Edit1.Text := Res; CloseFile( FC ); AssignFile ( FB, 'Test.Dat' ); Reset ( FB ); Res := ''; while not Eof(FB)do begin Read (FB,B); Str(B:3,S); Res:=Res+S; end; Edit2.Text:=Res; CloseFile(FB); end; end.
Результат:
Рис.2. Результат работы приложения
На следующем шаге мы рассмотрим текстовые файлы.