Процедуры Load и Store класса TStreamable и его потомков содержат параметры, делающие возможным чтение и запись методами классов TReader и TWriter (смотри файл помощи Component Writer's Help). Сохраняемая сущность меняется от класса к классу, поэтому для себя вы должны решить с чем вы будете работать.
Все классы, с которыми вы собираетесь работать через поток, должны быть зарегистрированы вызовом RegisterClass. Лично я это делаю в секции инициализации модуля, в котором определен данный класс.
Если еще во время разработки приложения вы знаете, объект какого класса вы будете сохранять/загружать и все, что вам нужно сделать, это инициализировать поток, filer и экземпляр объекта (только загрузка), то для этого можно использовать метод Load/Store.
Пример: (сохранение, FKnowObject - поле в TTest)
procedure TTest.StoreKnownObject(Filename: string); var S: TFileStream;W: TEnhWriter;begin S := TFileStream.Create(Filename, fmOpenWrite);W := TEnhWriter.Create(S, 1024);FKnownObject.Store(W);W.Free;S.Free;end; |
(загрузка объекта, сохраненного выше, предполагает, что до этого момента был осуществлен вызов FKnowObject.Create)
|
procedure TTest.LoadKnownObject(Filename: string); var S: TFileStream;R: TEnhReader;begin S := TFileStream.Create(Filename, fmOpenRead;R := TEnhReader.Create(S, 1024);FKnownObject.Load(R); {перезаписываем все предыдущие данные объекта}R.Free;S.Free;end; |
Имея список объектов, проще всего работать с ними в цикле.
Пример: (сохранение, список TKnownObjects)
procedure TTest.StoreKnownList(Filename: string; List: TList); var S: TFileStream;W: TEnhWriter;I: Integer;begin S := TFileStream.Create(Filename, fmOpenWrite;W := TEnhWriter.Create(S, 1024);W.WriteListBegin;with List dofor I := 0 to Count -1 doTKnownObject(Items[I]).Store(W);W.WriteListEnd;W.Free;S.Free;end; |
procedure TTest.StoreKnownList(Filename: string; List: TList); var S: TFileStream;R: TEnhReader;K: TKnownObject;begin S := TFileStream.Create(Filename, fmOpenRead;R := TEnhReader.Create(S, 1024);R.ReadListBegin;with List dowhile not EndOfList dobeginK.Create;K.Load(R);Add(K);end;R.ReadListEnd;end; |
function TEnhReader.ReadStreamable: TStreamable |
procedure TEnhReader.ReadListItems(List: TList); |
procedure TEnhWriter.WriteStreamable(AObj: TStreamable); |
procedure TEnhWriter.WriteListItems(List: TList); |
{Базовый класс и его расширения для работы с потоковыми объектами} {Авторские права принадлежат Don Croyle} unit Strmstuf; interface uses Classes; type TEnhReader = class;TEnhWriter = class; TStreamable = class(TPersistent)publicprocedure Load(R: TEnhReader); virtual;procedure Store(W: TEnhWriter); virtual;end; TStreamableClass = class of TStreamable; TEnhReader = class(TReader)publicprocedure ReadListItems(List: TList);function ReadStreamable: TStreamable;end; TEnhWriter = class(TWriter)publicprocedure WriteListItems(List: TList);procedure WriteStreamable(AObj: TStreamable);end; implementation procedure TStreamable.Load(R: TEnhReader); begin end; procedure TStreamable.Store(W: TEnhWriter); begin end; procedure TEnhReader.ReadListItems(List: TList); begin ReadListBegin;with List dobeginClear;while not EndOfList doAdd(ReadStreamable);end;ReadListEnd;end; function TEnhReader.ReadStreamable: TStreamable; begin Result := TStreamableClass(FindClass(ReadString)).Create;if Result <> nil then Result.Load(Self);end; procedure TEnhWriter.WriteListItems(List: TList); var I: Integer;begin WriteListBegin;with List dofor I := 0 to Count -1 doWriteStreamable(TStreamable(Items[I]));WriteListEnd;end; procedure TEnhWriter.WriteStreamable(AObj: TStreamable); begin WriteString(AObj.ClassName);AObj.Store(Self);end; end. |