Потоковая передача нескольких TObject-ов в TMemoryStream - PullRequest
2 голосов
/ 25 мая 2010

Мне нужно сохранить несколько объектов (большинство из них TObject / не являются постоянными) в TMemoryStream, сохранить поток на диск и загрузить его обратно. Объекты должны быть потоковыми один за другим. Какой-то универсальный контейнер.

В данный момент я помещаю все свойства / поля / переменные объекта в запись и сохраняю запись в поток. Но я намерен использовать функции file WriteInterger, WriteString (см. Ниже), WriteBoolean и др. Для сохранения / загрузки данных из потока.

StreamReadString(CONST MemStream: TMemoryStream): string; 
StreamWriteString(CONST MemStream: TMemoryStream; s: string);

Однако, похоже, мне нужно переписать много кода. Одним из многих примеров является TStringList.LoadFromStream, который не будет работать, поэтому его необходимо переписать. Это потому, что TStringList должен быть последним объектом в потоке (он читает с текущей позиции до конца потока).

Кто-нибудь знает библиотеку, которая обеспечивает базовые функции, подобные этой?


Я использую Delphi 7, поэтому RTTI не так уж и хорош.

Ответы [ 4 ]

1 голос
/ 25 мая 2010

См. Связанный пост здесь

Кстати, Delphi7 также имеет поддержку RTTI, иначе ваши формы (.dfm) не могут быть загружены :-)
Если вы используете опубликованные свойства, RTTI будет работать для вас "из коробки".
В противном случае вы должны сделать это самостоятельно с

procedure DefineProperties(Filer: TFiler); override;

Вы можете посмотреть, как это реализовано в:

procedure TDataModule.DefineProperties(Filer: TFiler);

Это единственные способы сериализации объектов.
Но вы также можете попробовать записи: если вы не используете массив (строки также являются массивами char) или свойства объекта, вы можете напрямую сохранить и загрузить запись в память (поток, файл и т. Д.). Я использую это в моем AsmProfiler , чтобы иметь возможность очень быстро читать и записывать многие (маленькие) результаты (массив записей с некоторыми целочисленными значениями может быть сохранен и загружен одним вызовом Move / CopyMemory!).

1 голос
/ 25 мая 2010

Почему бы не использовать XML?

  1. Напишите XSD для XML, который определяет XML.
  2. Создайте блочную форму Delphi для XSD с помощью мастера привязки данных XML.
  3. Поместите кучу ваших объектов в этот XML.
  4. Сохраните XML на диск (или передайте его на другой носитель).

Подробнее о XML и мастере привязки данных XML см. этот ответ .

Edit:

Просто отобразите ваши объекты на интерфейсы / объекты, сгенерированные из XSD; или используйте объекты / интерфейсы, которые были сгенерированы.

Обычно это гораздо проще, чем подключаться к потоковому механизму Delphi (либо написав обертки TPersistent с опубликованными свойствами вокруг ваших объектов, выбрав путь DefineBinaryProperty , либо TReader / TWriter / DefineProperty путь).

- Йерун

1 голос
/ 25 мая 2010

Задумывались ли вы об использовании TReader и TWriter для заполнения ваших потоков.

1 голос
/ 25 мая 2010

Какая версия Delphi? Delphi 2010 имеет новую функциональность RTTI, поэтому вы можете использовать DeHL , который имеет «полную универсальную сериализацию для всех включенных типов и коллекций».

...