10

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.

Erwin Mayer
  • 18,076
  • 9
  • 88
  • 126
  • 1
    That seems fairly unlikely, to be honest - or it may be a bug in DotNetZip. You could post a short but complete program, and maybe put a sample gzip file on a web site somewhere for us to test against? – Jon Skeet Sep 18 '11 at 14:51
  • OK let me prepare something... – Erwin Mayer Sep 18 '11 at 14:53
  • 1
    Out of interest, have you tried using System.IO.GZipStream instead? – Jon Skeet Sep 18 '11 at 15:00
  • I just tried with a very simple test (on a dedicated test project) and it works with System.IO.GZipStream, but fails as explained above with Ionic.Zlib.GZipStream... – Erwin Mayer Sep 18 '11 at 15:05
  • I was using 1.9.1.5, I'll check with the lastest update from August (the previous update was 2 years old). – Erwin Mayer Sep 18 '11 at 15:07
  • Done it, but now it throws `Bad CRC32 in GZIP trailer. (actual(EC084966)!=expected(8FC3EF16))`. I have updated the question with a link to a test project. I must be doing something wrong in the file generation, but I wonder why it works with the native .NET library. Thanks for your help! – Erwin Mayer Sep 18 '11 at 16:01

2 Answers2

6

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.

Erwin Mayer
  • 18,076
  • 9
  • 88
  • 126
  • 18 months later and I find this post because I have the same issue.. Did you ever find a fix? Looks like the product itself is dead - no new updates and no responses in their forums – The ZMan Apr 29 '13 at 17:16
  • I have not found a fix so far. – Erwin Mayer May 03 '13 at 05:17
  • I found some time to dig into this. – The ZMan Jun 04 '13 at 21:57
  • Sorry - hit enter.... Looking at the .Net version there is some CRC32 checking (see GZipDecoder.ReadFooter and Inflator.Decode if you have Reflector or equivalent). However that code only appear to be called as the stream is read and it gets to the end. However GZipStream doesn't override Close or Dispose so no checks are done when you do that. The code in DotNetZip that says //read to end of file is not doing that at all. The checksum needs 8 bytes so if there's less than 8 bytes in the buffer it reads enough bytes of the next block so that it has 8 bytes. – The ZMan Jun 04 '13 at 22:06
  • My workaround for this is that I've pulled the DotNetZip source into my code and modified Close such that it takes a bool that allows me to disable the CRC check. – The ZMan Jun 04 '13 at 22:07
  • 2
    One final note - you cant modify Close as its inherited. Instead I pass a flag into the GZipConstructor to indicate if the CRC should be checked. And a link to the DotNetZip discusssion... https://dotnetzip.codeplex.com/discussions/441615 - thanks all! – The ZMan Jun 04 '13 at 23:49
1

Check to make sure the drive you're writing to is not out of space. I had this error and it took me awhile but I figured out I was really out of space.