I am using the following code to uncompress a GZipStream (using DotNetZip library), where fs is a filestream pointing to a gz file (with FileMode.Open, FileAccess.Read, FileShare.ReadWrite):
using (var gz = new GZipStream(fs, CompressionMode.Decompress)) {
using (var sr = new StreamReader(gz)) {
header = sr.ReadLine();
}
}
But if the file is not read till the end (which I prefer to do when not needed as the file can be huge), it throws
ZlibException("Bad CRC32 in GZIP trailer. (actual(EC084966)!=expected(8FC3EF16))")
on the first closing bracket (actually when trying to Close() the StreamReader.
Now if call ReadToEnd() before closing the streamreader (or I read all lines using a while(!sr.EndOfStream) loop), it works.
I have observed the same behaviour with a 500 MB and 200 kB compressed file, so it seems it is not related to the file size.
Your insight is very welcome!
Here is a link to a simple dedicated test project.
It works with the System.IO.GZipStream library, so this is very strange.
As a conjecture, I suspect that if the CRC block is at the end of the file, then if I abort reading the stream, it cannot have verified the integrity while disposing the stream and therefore throws the exception.
However this would not explain why it works when using
System.IO.GzipStream.I found the relevant part of the source code of DotNetZip here, but it seems they are checking that the stream is read to the end (see
// Make sure we have read to the end of the stream). Then, they do compute a CRC32 as the exception message shows one.