Мы внедрили оптимизированный двоичный формат для сериализации записей и массивов. Вы также можете легко сериализовать любой объект структуры памяти. Он оптимизирован для скорости и используемого пространства.
Это часть нашего проекта с открытым исходным кодом 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;