views:

125

answers:

1

The following code throws an EZDecompressionError with message 'Invalid ZStream operation' whenever the line

Reader.Free

is executed. Can someone tell me what's wrong with this code?

Reader := nil;
Decompressor := nil;
InputFile := TFileStream (FileName, fmOpenRead);
try
  Decompressor := TDecompressionStream.Create (InputFile);
  Reader := TReader.Create (Decompressor, 1024);
  SomeString := Reader.ReadString;
finally
  Reader.Free
  Decompressor.Free;
  InputFile.Free;
end;

I tested to change the order of the memory freeing commands but that doesn't seem to help. Leaving out the Reader.Free line of course results in a memory leak.

+3  A: 

Smasher

TReader does a FStream.Seek(FBufPos - FBufCount, soCurrent) in its destructor.

The error get's raised because of a backwards seek. If you call Reader.FlushBuffer and Reader.Position := soFromBeginning before freeing the reader, does the error disappear?


From the comments of TDecompressionstream. TDecompressionStream is read-only and unidirectional; you can seek forward in the stream, but not backwards.

Regards,
Lieven

Lieven
The error does not disappear unfortunately...this must be a pretty common usage scenario...I'm really confused...thanks for looking into that!
Smasher
The error get's raised because the destructor of TReader probably does a backwards search in your stream. Somehow you have to make sure that this is changed into a forward search to circumvent the exception.
Lieven
still crashing :( Is TReader not supposed to be used in conjunction with TDecompressionStream?
Smasher
How about decompressing to a TMemoryStream and then use that for the TReader?
Lars Truijens
@Smasher. I believe Lars' solution would work. Thanks for stepping in Lars. It "is" odd though as it does looks like a common enough scenario.
Lieven
Thank you two for your help! It does work when first decompressing into a TMemoryStream. Nice workaround, but if anybody understands why exactly this isn't working as initially expected, feel free to answer.
Smasher
The reason's pretty clear, actually: It wants to leave your stream in the same state in which it found it. It just doesn't quite understand the concept of a unidimensional stream.
Mason Wheeler