寻找二进制编码的序列化机制

时间:2012-03-30 01:11:25

标签: delphi serialization binary protocols

我已经准备好开发内部通信协议,并尝试使用XML或JSON作为序列化机制,但文本模式效率较低,并导致大量数据包。所以,我希望使用二进制序列化编码机制。但是,我找了很久,找不到跨语言,Delphi支持的机制。

4 个答案:

答案 0 :(得分:3)

Google Protocol BuffersMessagePack是最有效的方案,遗憾的是目前Delphi的端口非常少。

如果你愿意为自己实现(messagepack非常简单),我建议你破解现有库的 write() parse()函数,例如{{ 3}}

你最终会得到一个非常体面的图书馆。

答案 1 :(得分:2)

Apache Thrift支持Delphi XE和2010。

答案 2 :(得分:0)

我们为记录和数组序列化实现了优化的二进制格式。您还可以轻松地序列化任何内存结构对象。它针对速度和使用空间进行了优化。

它是我们的mORMot开源项目的一部分,从Delphi 5到XE2。您不必使用项目的整个ORM /客户端 - 服务器服务功能,只需使用SynCommons.pas单元。

然后,您可以使用我们的 SynLZ 实时压缩格式,使结果内容更小。

请参阅this blog article及相关的源代码。

它具有比序列化更多的功能(即排序,查找,散列,切片,反转......)。

它可以与TFileBufferWriter/TFileBufferReader类一起使用来创建任何自定义格式,使用整数的可变长度编码以及其他一些优化。

例如,我们使用此序列化将所有符号的.map文件存储为.mab二进制格式:它使用一些TDynArray实例+ SynLZ 。对于4.44 MB的.map文本文件,它会创建一个378 KB的.mab。请参阅TSynMapFile.SaveToStream和其他。

我们使用这种相同的格式来保存内存中的对象列表(请参阅TSQLRestServerStaticInMemory中的SQLite3Commons.pas类)。例如,502 KB People.json内容存储在92 KB People.data二进制文件中。

只是一个代码段:

function TSQLRestServerStaticInMemory.SaveToBinary(Stream: TStream): integer;
var W: TFileBufferWriter;
    MS: THeapMemoryStream;
    IDs: TIntegerDynArray;
    i, n, f: integer;
begin
  result := 0;
  if (self=nil) or (Stream=nil) then
    exit;
  MS := THeapMemoryStream.Create;
  W := TFileBufferWriter.Create(MS);
  try
    // primitive magic and fields signature for file type identification
    W.Write(RawUTF8(ClassName));
    W.Write(StoredClassProps.SQLTableName);
    n := Length(StoredClassProps.FieldsName);
    W.WriteRawUTF8DynArray(StoredClassProps.FieldsName,n);
    W.Write(pointer(StoredClassProps.FieldType),sizeof(TSQLFieldType)*n);
    // write IDs
    SetLength(IDs,Count);
    with fValue do
      for i := 0 to Count-1 do
        IDs[i] := TSQLRecord(List[i]).fID;
    W.WriteVarUInt32Array(IDs,Count,wkSorted); // efficient ID storage
    // write content, grouped by field (for better compression)
    for f := 0 to High(fStoredClassProps.Fields) do
      with fStoredClassProps.Fields[f]^, fValue do
        for i := 0 to Count-1 do
          GetBinary(TSQLRecord(List[i]),W);
    W.Flush;
    result := StreamSynLZ(MS,Stream,TSQLRESTSERVERSTATICINMEMORY_MAGIC);
  finally
    W.Free;
    MS.Free;
  end;
end;

答案 3 :(得分:0)

BEncode?

以下是Delphi源代码: http://www.torry.net/quicksearchd.php?String=bencode&Title=Yes

维基百科写道: http://en.wikipedia.org/wiki/Bencode

其他语言也有源代码。