Реализация класса


{ FILEIO.PAS - Файловый ввод/вывод для программ-фильтров Автор: Джим Мишель Дата последней редакции: 04/05/97 } {$I+} { Использовать исключения для обработки ошибок } unit fileio; interface type FileIOMode = (fioNotOpen, fioRead, fioWrite);
BuffArray = array[0..1] of byte; pBuffArray = ^BuffArray; TFilterFile = class (TObject) private FFilename : String; F : File; FBufferSize : Integer; FBuffer : pBuffArray; FBytesInBuff : Integer; FBuffIndx : Integer; FFileMode : FileIOMode; function ReadBuffer : boolean; function WriteBuffer : boolean; public constructor Create (AName : String; ABufSize : Integer);
destructor Destroy; override; function Open (AMode : FileIOMode) : Boolean; procedure Close; function Eof : Boolean; function GetByte : byte; function PutByte (b : byte) : boolean; end; implementation { TFilterFile } { Create - подготавливает, но не открывает файл } constructor TFilterFile.Create ( AName : String; ABufSize : Integer );
begin inherited Create; FFilename := AName; FBufferSize := ABufSize; FBytesInBuff := 0; FBuffIndx := 0; FFileMode := fioNotOpen; { Назначаем, но не открываем } Assign (F, FFilename);
{ Выделяем память для буфера } GetMem (FBuffer, FBufferSize);
end; { Destroy - закрывает файл (если он открыт) и уничтожает объект } destructor TFilterFile.Destroy; begin { Если файл открыт, закрываем его } if (FFileMode <>
fioNotOpen) then begin Self.Close; end; { Если был выделен буфер, освобождаем его } if (FBuffer <>
Nil) then begin FreeMem (FBuffer, FBufferSize);
FBuffer := Nil; end; inherited Destroy; end; { Open - открыть файл в нужном режиме } function TFilterFile.Open ( AMode : FileIOMode ) : Boolean; var SaveFileMode : Byte; begin Result := True; SaveFileMode := FileMode; { переменная FileMode определена в модуле System } { Пытаемся открыть файл } try case AMode of fioRead : begin FileMode := 0; Reset (F, 1);
end; fioWrite : begin FileMode := 1; Rewrite (F, 1);
end; end; FFileMode := AMode; except Result := False; end; FBytesInBuff := 0; FBuffIndx := 0; FileMode := SaveFileMode; end; { Close - закрывает файл, при необходимости сбрасывая буфер } procedure TFilterFile.Close; begin { Если буфер записи не пуст, записываем его } if ((FFileMode = fioWrite) and (FBytesInBuff >
0)) then begin WriteBuffer; end; try { Закрываем файл } System.Close (F);
finally FFileMode := fioNotOpen; end; end; { ReadBuffer - читает блок из файла в буфер } function TFilterFile.ReadBuffer : Boolean; begin Result := True; if (Self.Eof) then begin Result := False; end else begin try BlockRead (F, FBuffer^, FBufferSize, FBytesInBuff);
except Result := False; end; end; end; { GetByte - возвращает следующий байт из файла. При необходимости читает из файла в буфер } function TFilterFile.GetByte : byte; begin if (FBuffIndx >
= FBytesInBuff) then begin if (not ReadBuffer) then begin Result := 0; Exit; end else begin FBuffIndx := 0; end; end; Result := FBuffer^[FBuffIndx]; Inc (FBuffIndx);
end; { WriteBuffer - записывает блок из буфера в файл } function TFilterFile.WriteBuffer : Boolean; begin Result := True; try BlockWrite (F, FBuffer^, FBytesInBuff);
except Result := False; end; if (Result = True) then begin FBytesInBuff := 0; end; end; { PutByte - заносит байт в буфер. При необходимости записывает буфер в файл } function TFilterFile.PutByte (b : byte) : Boolean; begin if (FBytesInBuff = FBufferSize) then begin if (not WriteBuffer) then begin Result := False; Exit; end else begin FBytesInBuff := 0; end; end; FBuffer^[FBytesInBuff] := b; Inc (FBytesInBuff);
Result := True; end; { Eof - возвращает True, если был достигнут конец входного файла } function TFilterFile.Eof : Boolean; begin Result := (FBuffIndx >
= FBytesInBuff);
if Result then begin try Result := System.Eof (F);
except Result := True; end; end; end; end.

Поскольку класс TFilterFile почти все делает сам, использовать его вместо стандартного текстового файла ввода/вывода оказывается очень просто. Тем не менее скорость работы меняется прямо на глазах. Новая процедура DoFilter из листинга 1.9 использует класс TFilterFile для выполнения файловых операций. Получившаяся программа работает намного быстрее первоначальной версии. А самое приятное заключается в том, что прочесть или понять ее оказывается ничуть не сложнее, чем предыдущий, медленный вариант.



Содержание раздела