Фундаментальные алгоритмы и структуры данных в Delphi | страница 54
Есть еще один вопрос, который проще рассмотреть на примере кода. Было бы довольно глупо ограничить концепцию постоянных (устойчивых) массивов только до файлов на диске. Несмотря на то что в подавляющем большинстве случаев будут использоваться файлы, ничто не мешает нам организовать постоянный массив в памяти или на любом другом устройстве хранения данных. Было бы удобно иметь класс постоянного массива, который пользуется потоками. В Delphi предусмотрен богатый набор классов потоков, включая файловый поток. Таким образом, если мы напишем код, использующий класс TStream, его можно будет применять со всеми другими классами, порожденными от TStream.
Ниже приведен код класса TtdRecordStream - класса, предназначенного для постоянного хранения в потоке массива записей.
Листинг 2.18. Класс TtdRecordStream для хранения постоянных массивов.
type
TtdRecordStream = class private
FStream : TStream;
FCount : longint;
FCapacity : longint;
FHeaderRec : PtdRSHeaderRec;
FName : TtdNameString;
FRecord : PByteArray;
FRecordLen : integer;
FRecordLen4 : integer;
FZeroPosition : longint;
protected
procedure rsSetCapacity(aCapacity : longint);
procedure rsError(aErrorCode : integer; const aMethodName : TtdNameString; aNumValue : longint);
function rsCalcRecordOffset(aIndex : longint): longint;
procedure rsCreateHeaderRec(aRecordLen : integer);
procedure rsReadHeaderRec;
procedure rsReadStream(var aBuffer; aBufLen : integer);
procedure rsWriteStream(var aBuffer; aBufLen : integer);
procedure rsSeekStream(aOffset : longint);
public
constructor Create(aStream : TStream; aRecordLength : integer);
destructor Destroy; override;
procedure Flush; virtual;
function Add(var aRecord): longint;
procedure Clear;
procedure Delete(aIndex : longint);
procedure Read(aIndex : longint; var aRecord; var alsDeleted : boolean);
procedure Write(aIndex : longint; var aRecord);
property Capacity : longint read FCapacity write rsSetCapacity;
property Count : longint read FCount;
property RecordLength : integer read FRecordLen;
property Name : TtdNameString read FName write FName;
end;
К сожалению, для такого типа постоянных массивов очень сложно перегрузить операцию [], поэтому в классе TtdRecordStream свойство Items не используется. Вместо него введены простые методы Read и Write.
Конструктор Create может вызываться в двух режимах: для постоянного массива в потоке или не в потоке. Режим определяется самим конструктором и в случае, если используется новый поток, создается служебный блок.