是否有任何Delphi序列化库能够序列化记录和记录数组而不是类?
答案 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;
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。
事实上,它实现了:
RecordEquals, RecordSave, RecordSaveLength, RecordLoad
; TDynArray
对象,它是任何动态数组的包装器,能够在任何动态数组周围显示类似TList的方法,甚至包含记录,字符串或其他动态数组。它能够序列化任何动态数组。序列化使用优化的二进制格式,并且能够将任何记录或动态数组保存并加载为RawByteString
。您还有手头的JSON序列化,包括自定义布局 - 请参阅sustom JSON serialization of records。
答案 3 :(得分:0)
作为记录,如果你没有属性,我不相信你会更进一步,试图使用任何持久性框架(如DeHL)。
在技术上正确的情况下,接受的答案在实际实用程序中是可疑的,并且如果您在生产中使用它,则会有许多长期支持 - 噩梦场景。不要这样做。
如果你的节目只是一些临时性的话,我可以谦虚地建议你用一个“记录文件”摇滚老派,这是一种经典的Turbo Pascal技术仍然适用。