I have to agree with the OP. The requirement to call SkipEntry() breaks the design pattern for streams, and for any IDisposable. If an object owns an IDisposable, it should be able to dispose it, without knowledge of its precise implementation. So although I agree it's a bit annoying that StreamReader owns the stream, it's not incorrect, as long as it is well documented.
In my case, I pass the EntryStream to pre-existing code, which has no idea that it comes from a zip. It creates and disposes a StreamReader, so tries to dispose the stream as well, at which point the exception is thrown. It deliberately does not always read the whole stream. Also, if an exception is thrown while processing the data, it gets wiped out by the "not fully consumed" exception, and so never gets noticed.
I understand the point about not wanting to leave the compressed stream at an unknown point. But usually the whole archive will be closed, so would not be a problem anyway. So I suppose there are 2 possible changes:
In my case, I pass the EntryStream to pre-existing code, which has no idea that it comes from a zip. It creates and disposes a StreamReader, so tries to dispose the stream as well, at which point the exception is thrown. It deliberately does not always read the whole stream. Also, if an exception is thrown while processing the data, it gets wiped out by the "not fully consumed" exception, and so never gets noticed.
I understand the point about not wanting to leave the compressed stream at an unknown point. But usually the whole archive will be closed, so would not be a problem anyway. So I suppose there are 2 possible changes:
- Call "SkipEntry()" from inside EntryStream.Dispose(), if not complete. Not ideal. The files I am currently reading are huge, and if an exception occurs while reading, it is quite likely to be on line 1. So it's hugely inefficient to read and discard the whole stream.
-
Leave the stream where it is, but have the reader throw an exception if/when the next entry is requested, if the previous EntryStream did not complete. Not exactly sure the best way to do that - maybe add a boolean property "EntryComplete" to the reader, assigned from the EntryStream on dispose.