Delphi(win32)序列化库

时间:2010-06-06 13:38:25

标签: delphi serialization

是否有任何Delphi序列化库能够序列化记录和记录数组而不是类?

4 个答案:

答案 0 :(得分:6)

@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.

答案 1 :(得分:3)

如果您有Delphi 2010,您可能需要查看DeHL。它包含一个可以处理几乎任何数据类型的序列化库。

答案 2 :(得分:3)

另一个解决方案,从Delphi 5到XE2,可用in one of our OpenSource unit

事实上,它实现了:

  • 用于处理记录类型的一些低级RTTI函数:RecordEquals, RecordSave, RecordSaveLength, RecordLoad;
  • 一个专用的TDynArray对象,它是任何动态数组的包装器,能够在任何动态数组周围显示类似TList的方法,甚至包含记录,字符串或其他动态数组。它能够序列化任何动态数组。

序列化使用优化的二进制格式,并且能够将任何记录或动态数组保存并加载为RawByteString。您还有手头的JSON序列化,包括自定义布局 - 请参阅sustom JSON serialization of records

答案 3 :(得分:0)

作为记录,如果你没有属性,我不相信你会更进一步,试图使用任何持久性框架(如DeHL)。

在技术上正确的情况下,接受的答案在实际实用程序中是可疑的,并且如果您在生产中使用它,则会有许多长期支持 - 噩梦场景。不要这样做。

如果你的节目只是一些临时性的话,我可以谦虚地建议你用一个“记录文件”摇滚老派,这是一种经典的Turbo Pascal技术仍然适用。