Delphi (win32) библиотеки сериализации - PullRequest
5 голосов
/ 06 июня 2010

Существуют ли какие-либо библиотеки сериализации Delphi, способные сериализировать записи и массивы записей вместо классов?

Ответы [ 4 ]

6 голосов
/ 06 июня 2010

@ Max вы можете использовать компонент TJvAppXMLFileStorage из JEDI для сериализации записи или массива записей.

Вы можете использовать процедуру под названием WriteBinary для хранения данных и ReadBinary для чтения.

к сожалению, документации по этому компоненту не так много, поэтому здесь у вас есть очень простой пример для хранения одной записи (для массива записей вы можете легко изменить этот исходный код).

Структура записи

type
  MyRecord= record
      Field1 : Integer;
      Field2 : Double;
      Field3 : String[20];
      Field4 : String[20];
  end;

Сохранить запись

Procedure SaveMyRecord(Rec : MyRecord);
var
  MyStore: TJvAppXMLFileStorage;
begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.FileName:='C:\temp\record.xml'; 
    //this component supports store multiples objects to the same file, so you need use an identifier for you particular object, in this case i'm use the Dummy name.
    MyStore.WriteBinary('Dummy', @Rec,sizeof(Rec));
    MyStore.Xml.SaveToFile(MyStore.FileName);
  finally
    MyStore.Free;
  end;
end;

эта процедура создает XML-файл, подобный этому, данные кодируются в шестнадцатеричном формате.

<?xml version="1.0" encoding="iso-8859-1"?>
<Configuration>
  <Dummy>84030000000000003333333333331F400D737472696E6720746573742031000000000000000D737472696E672074657374203200000000000000000000000000</Dummy>
</Configuration>

Чтение сохраненных данных

Procedure LoadMyRecord(var Rec : MyRecord);
var
  MyStore: TJvAppXMLFileStorage;
begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.FileName:='C:\temp\record.xml';//point to the same file
    MyStore.Xml.LoadFromFile(MyStore.FileName); //load the file
    MyStore.ReadBinary('Dummy', @Rec,sizeof(Rec));//use the Dummy identifier and pass the record as an pointer
  finally
    MyStore.Free;
  end;
end;

Проверьте этот полный проект (проверено в Delphi 7)

program ProjectPersistRecord;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  JvAppXMLStorage;

type
  MyRecord= record
      Field1 : Integer;
      Field2 : Double;
      Field3 : String[20];
      Field4 : String[20];
  end;

Procedure SaveMyRecord(Rec : MyRecord);
var
  MyStore: TJvAppXMLFileStorage;
begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.FileName:='C:\temp\record.xml';
    MyStore.WriteBinary('Dummy', @Rec,sizeof(Rec));
    MyStore.Xml.SaveToFile(MyStore.FileName);
  finally
    MyStore.Free;
  end;
end;

Procedure LoadMyRecord(var Rec : MyRecord);
var
  MyStore: TJvAppXMLFileStorage;
begin
  MyStore:= TJvAppXMLFileStorage.Create(nil);
  try
    MyStore.FileName:='C:\temp\record.xml';
    MyStore.Xml.LoadFromFile(MyStore.FileName);
    MyStore.ReadBinary('Dummy', @Rec,sizeof(Rec));
  finally
    MyStore.Free;
  end;
end;


Var
    Rec :  MyRecord;
begin
  //Fill the record
  Rec.Field1:=900;
  Rec.Field2:=7.8;
  Rec.Field3:='string test 1';
  Rec.Field4:='string test 2';
  SaveMyRecord(Rec); //save the record
  FillChar(Rec,SizeOf(Rec),#0); //clear the record variable
  LoadMyRecord(Rec);//restire the record data
  //show the loaded data
  Writeln(rec.field1);
  Writeln(rec.field2);
  Writeln(rec.field3);
  Writeln(rec.field4);
  Readln;
end.
3 голосов
/ 29 июня 2012

Другое решение, работающее от Delphi 5 до XE2, доступно в одном из наших модулей OpenSource .

На самом деле, он реализует:

  • Некоторые функции RTTI низкого уровня для обработки типов записей: RecordEquals, RecordSave, RecordSaveLength, RecordLoad;
  • Выделенный TDynArray объект, который является оболочкой для любого динамического массива, способный предоставлять методы, подобные TList, для любого динамического массива, даже содержащего записи, строки или другие динамические массивы. Он может сериализовать любой динамический массив.

Сериализация использует оптимизированный двоичный формат и может сохранять и загружать любую запись или динамический массив как RawByteString. У вас под рукой также есть сериализация JSON, включая пользовательский макет - см. Пользовательская сериализация JSON записей .

3 голосов
/ 06 июня 2010

Если у вас Delphi 2010, вы можете взглянуть на DeHL . Он содержит библиотеку сериализации, которая может обрабатывать практически любые типы данных.

0 голосов
/ 10 июня 2010

Будучи рекордом, если у вас нет свойств, я не верю, что вы продвинулись дальше, пытаясь использовать любую из сред персистентности (например, DeHL).

Принятый ответ, хотя и технически правильный, сомнителен в реальной полезности и имеет много долгосрочных сценариев поддержки и кошмара, если вы используете его в работе. НЕ ДЕЛАЙТЕ ЭТОГО.

Если ваша программа - просто специальная программа, позвольте мне смиренно предложить вам сделать это в старом стиле с «файлом записей», классической техникой Turbo Pascal, которая все еще работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...