Сжатие TComponents при записи их в TStream - PullRequest
5 голосов
/ 22 мая 2009

Некоторые приложения, которые мы используем, зависят от потомков TComponent, чтобы легко сохранять / загружать состояние своих внутренних объектов с помощью Write / ReadComponentResFile

function TSomeClass.SaveState: boolean;
begin
  ...
  try
    ...
    WriteComponentResFile(self.f_path, TComponent(self));
    result := true;
  except   
    result := false;
  end;
  ....
end;

Теперь мы хотели бы сжать эти данные, но по какой-то причине я не смог найти способ написать аналогичную функцию с использованием потокового класса JCL bzip2, что-то о операции поиска не поддерживается

Поскольку я не эксперт TStream, я хотел бы узнать, как проще всего реализовать такое сжатие; работа с TComponent для чтения / записи?

Спасибо

1 Ответ

14 голосов
/ 22 мая 2009

TComponent, очевидно, хочет иметь возможность искать в потоке, из которого он читает или пишет, и вы, как правило, не можете сделать это со сжатыми потоками - по крайней мере, не в обратном направлении. После того, как вы прочитали байт, вы не сможете вернуться и прочитать его снова, потому что то, какое именно значение вы получите, может зависеть от всего содержимого потока, которое привело к этому байту. Попытка перечитать один байт назад может означать перечитывание всего потока. И для записи, чтобы вернуться назад и «исправить» некоторую область потока, изменение одного байта будет означать необходимость повторного сжатия всего, что появилось после него. Таким образом, вы можете понять, почему сжатые потоки не любят искать в обратном направлении.

Запишите свои данные в TMemoryStream, а затем скопируйте содержимое этого потока в сжатый поток. Чтобы прочитать, скопируйте декомпрессионный поток в TMemoryStream и затем загрузите ваши компоненты оттуда. (Не забудьте установить свойство Position в ноль до загрузки компонента из потока памяти.)

...