Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compress TComponents while writing them in a TStream

Some application we're using depends on TComponent descendants to easily save/load the state of its internal objects, with the help of Write/ReadComponentResFile

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

Now we would like to compress this data, but for some reason I've been unable to find a way to write similar function using the JCL bzip2 stream class, something about seek operation not being supported

As I am no TStream expert, I would like to know the easiest way for me to implement such a compression; working with TComponent read/write ?

Thanks

like image 730
Lepidosteus Avatar asked May 21 '09 21:05

Lepidosteus


1 Answers

TComponent apparently wants to be able to seek in the stream it reads from or writes to, and you generally can't do that with compressed streams — at least not backward. Once you've read a byte, you can't go back and read it again because precisely what value you get may depend on the entire stream contents that led to that byte in the first place. Seeking backward to re-read one byte could mean re-reading the entire stream. And for writing, to go back and "fix up" some region of the stream, changing one byte would mean needing to recompress everything that came after it. So you can see why compressed streams don't like to seek backward.

Write your data to a TMemoryStream, and then copy that stream's contents to a compressed stream afterward. To read, copy the decompression stream into a TMemoryStream and then load your components from there. (Don't forget to set the Position property back to zero before loading the component out of the memory stream.)

like image 52
Rob Kennedy Avatar answered Oct 17 '22 06:10

Rob Kennedy