Шаг 88.
Типизированные файлы

    На этом шаге мы рассмотрим средства работы с типозированными файлами.

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

    Пример недопустимых объявлений:

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. Результат работы приложения

    На следующем шаге мы рассмотрим текстовые файлы.




Предыдущий шаг Содержание Следующий шаг