NewOffset : longint;

begin

NewOffset := FStream.Seek(aOffset, soFromBeginning);

if (NewOffset <> aOffset) then

rsError(tdeRSSeekError, 'rsSeekStream', aOffset);

end;

procedure TtdRecordStream.rsWriteStream(var aBuffer;

aBufLen : integer);

var

BytesWritten : longint;

begin

BytesWritten := FStream.Write(aBuffer, aBufLen);

if (BytesWritten <> aBufLen) then

rsError(tdeRSWriteError, 'rsWriteStream', aBufLen);

Flush;

end;

Как видите, если результат выполнения одного из методов не соответствует ожидаемому, методы вызывают исключения.

Существует еще один метод, о котором мы не говорили, - rsWriteStream. Фактически это метод Flush - виртуальный метод, предназначенный для сброса содержащихся в потоке данных на связанное с потоком устройство (например, диск). Его реализация для нашего класса представляет собой пустую подпрограмму, поскольку мы не знаем, как сбросить данные из стандартного потока TStream. Он существует только для того, чтобы быть перекрытым в дочерних классах, которые имеют дело с потоком, связанным с диском, например, файловым потоком.

Листинг 2.28. Реализация постоянных массивов с помощью файлового потока

constructor TtdRecordFile.Create(const aFileName : string;

aMode : word;

aRecordLength : integer);

begin

FStream := TFileStream.Create(aFileName, aMode);

inherited Create(FStream, aRecordLength);

FFileName := aFileName;

Mode := aMode;

end;

destructor TtdRecordFile.Destroy;

begin

inherited Destroy;

FStream.Free;

end;

procedure TtdRecordFile.Flush;

{$IFDEF Delphi1}

var

DosError : word;

Handle : THandle;

begin

Handle := FStream.Handle;

asm

mov ah, $68

mov bx, Handle

call D0S3Call

jc @@Error

xor ax, ax

@6Error:

mov DosError, ax

end;

if (DosError <> 0) then

rsError(tdeRSFlushError, 'Flush', DosError)

end;

{$ENDIF}

{$IFDEF Delphi2Plus}

begin

if not FlushFileBuffers (FStream.Handle) then

rsError(tdeRSFlushError, 'Flush', GetLastError)

end;

{$ENDIF}

В приведенном коде присутствует перекрытый метод Flush, который сбрасывает данные в дескриптор, связанный с файловым потоком, содержащим постоянный массив. Реализации для Delphi1 и для 32-битных версий будут отличаться, поскольку процесс сброса данных в дескриптор в этих версиях различен.

Полный код класса TtdRecordStream можно найти на Web-сайте издательства, в разделе материалов. После выгрузки материалов отыщите среди них файл TDRecFil.pas.

Резюме

Эта глава была посвящена массивам - одной из фундаментальных структур данных. Были описаны их достоинства (доступ к отдельным элементам составляет O(1), поддерживается локальность ссылок) и недостатки (вставка и удаление элементов относятся к операциям класса О(n)). Приведена реализация класса массива TtdRecordList. Затем был подробно рассмотрен стандартный класс TList и его простой дочерний класс TtdObjectList.

Кроме того, мы познакомились с реализацией постоянных массивов в форме потока записей. Был приведен пример реализации класса постоянных массивов, TtdRecordStream, который позволяет выполнять чтение, запись и удаление отдельных записей.

Глава 3. Связные списки, стеки и очереди

Как и массивы, связные списки представляют собой универсальную структуру данных, широко используемую многими программистами. Однако, в отличие от массивов, связные списки не входят в состав стандартного языка Object Pascal. Тем не менее, в Object Pascal создать связный список достаточно просто. Все что для этого нужно - наличие в составе языка указателя, хотя фактически могут использоваться и классы или объекты.

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

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

Отметить Добавить цитату