Сергей Прохоренко писал(а):
Посмотрел TIFF более подробно. Всё-таки этот формат предназначен для других целей - для хранения изображений и прочих однородных данных. Нам же нужно хранить деревья и таблицы, состоящие из записей. Для этого нужно в языке разметки иметь "тагированные" операторные скобки - именно то, что есть в XML, но нет в TIFF. Хотя у TIFF есть несомненное достоинство - не нужно искать закрывающую скобку, а достаточно отсчитать SIZE байтов от открывающей скобки, что позволяет сделать более быстрый парсер для данных простой структуры (это, к сожалению, не наш случай).
Мне кажется, вы недостаточно полно оценили возможности "простого" формата. У меня в файл пишется именно дерево объектов, но при этом некоторые объекты (TCurve - графики полученных от прибора данных) позволяют себе сохранять массивы данных типа array of real безо всякого дополнительного кодирования - просто бинарным дампом памяти. Очень просто и эффективно. Дерево объектов:
Код:
(TMainForm
(TArchiveInfo)
3x(TChannelData
(TStandardParams)
(TAdditionParams)
(TSampleParams)
(TAnalyzeParams)
0..6x(TMarkerDatas)
1..9x(TCurve
6x(TPeak)
12x(TMarkerDatas)
(TAnalyzeParams)
)
)
(TValMethod
1..6x(TValMethodElement)
1..8x(TValMethodStage)
(TValMethodSweep
0..Nx(TSweepPause)
)
(TWashSettings)
(TTreatmentParams)
)
)
Каждый объект сохраняет свои данные плюс предоставляет возможность сохраниться вложенным объектам. Объект типа TMainForm сохраняет какие-то свои настройки, в том числе объект типа TArchiveInfo, объект типа TValMethod и три объекта типа TChannelData. Каждый из них, в свою очередь, сохраняет собственные данные (не показаны на карте) плюс вложенные объекты. Скелет кода на Delphi:
Код:
procedure TMainForm.SaveToStream(Stream: TStream);
begin
Stream.Write(tag_ArchiveInfo);
Stream.Write(Self.FArchiveInfo.GetStreamSize);
Self.FArchiveInfo.SaveToStream(Stream);
...
end;
procedure TMainForm.LoadFromStream(Stream: TStream; StopPos: Integer);
var Tag, Size: Integer;
begin
while Stream.Position < StopPos do
beign
Stream.Read(Tag);
Stream.Read(Size);
case Tag of
tag_ArchiveInfo:
Self.FArchiveInfo.LoadFromStream(Stream, Stream.Position + Size);
...
else
Stream.Seek(Size, soFromCurrent);
end;
end;
end;
Можно реализовать и без GetStreamSize, добавив скобки типа Stream.BeginData/EndData, а заодно избавиться от параметра StopPos, но я не стал заморачиваться.
Простота или сложность структуры ни при чём. В поле Data любого тэга любой объект может хранить что угодно, в том числе данные других объектов, сколь угодно сложных.