Ищем механизм сериализации в двоичном коде - PullRequest
4 голосов
/ 30 марта 2012

Я был готов разработать протокол внутренней связи и пытался использовать XML или JSON в качестве механизма сериализации, но текстовый режим менее эффективен и приводит к большому объему пакетов.Итак, я надеюсь использовать механизм кодирования двоичной сериализации.Однако я долго искал, не мог найти кросс-языковой, поддерживаемый Delphi механизм.

Ответы [ 4 ]

3 голосов
/ 30 марта 2012

Буферы протокола Google и MessagePack являются самыми эффективными схемами из всех, к сожалению, на данный момент очень мало портов для Delphi.http://sourceforge.net/projects/protobuf-delphi/

Если вы хотите реализовать это для себя (пакет сообщений действительно прост), я предлагаю вам взломать write () и parse () функции существующих библиотек, такие как SuperObject .

В результате вы получите очень приличную библиотеку без особых усилий.

2 голосов
/ 25 мая 2012

Apache Thrift поддерживает Delphi XE и 2010.

0 голосов
/ 30 марта 2012

BEncode?

Вот источник Delphi: http://www.torry.net/quicksearchd.php?String=bencode&Title=Yes

Википедия пишет об этом: http://en.wikipedia.org/wiki/Bencode

Там есть и исходные коды для других языков.1009 *

0 голосов
/ 30 марта 2012

Мы внедрили оптимизированный двоичный формат для сериализации записей и массивов. Вы также можете легко сериализовать любой объект структуры памяти. Он оптимизирован для скорости и используемого пространства.

Это часть нашего проекта с открытым исходным кодом mORMot, работает от Delphi 5 до XE2. Вам не нужно использовать все возможности служб ORM / Client-Server проекта, только модуль SynCommons.pas.

Затем вы можете использовать наш SynLZ формат сжатия в реальном времени, чтобы сделать результирующее содержимое еще меньше.

См. эту статью блога и соответствующий исходный код.

Он имеет больше возможностей, чем сериализация (т.е. сортировка, поиск, хэширование, нарезка, реверсирование ...).

Может использоваться с TFileBufferWriter/TFileBufferReader классами для создания любого пользовательского формата с кодированием переменной длины целых чисел и некоторыми другими оптимизациями.

Например, мы используем эту сериализацию для хранения файла .map всех символов в двоичном формате .mab: он использует несколько TDynArray instance + SynLZ . Для текстового файла .map 4,44 МБ создается файл .mab 378 КБ. См. TSynMapFile.SaveToStream и др.

Мы используем этот же формат для сохранения списка объектов в памяти (см. TSQLRestServerStaticInMemory класс в SQLite3Commons.pas). Например, содержимое размером 502 КБ People.json сохраняется в двоичном файле размером 92 КБ 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;
...