1

I have some GZ compressed resources in my program and I need to be able to write them out to temporary files for use. I wrote the following function to write the files out and return true on success or false on failure. In addition, I've put a try/catch in there which shows a MessageBox in the event of an error:

private static bool extractCompressedResource(byte[] resource, string path)
{
  try
  {
    using (MemoryStream ms = new MemoryStream(resource))
    {
      using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite))
      {
        using (GZipStream zs = new GZipStream(fs, CompressionMode.Decompress))
        {
          ms.CopyTo(zs); // Throws exception

          zs.Close();
          ms.Close();
        }
      }
    }
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.Message); // Stream is not writeable
    return false;
  }

  return true;
}

I've put a comment on the line which throws the exception. If I put a breakpoint on that line and take a look inside the GZipStream then I can see that it's not writeable (which is what's causing the problem).

Am I doing something wrong, or is this a limitation of the GZipStream class?

Ozzah
  • 10,631
  • 16
  • 77
  • 116
  • 2
    No need to close streams in a "using" block, they will be closed automatically when they are disposed – musefan Nov 17 '11 at 01:46
  • 1
    Also, as written, GZipStream will dispose of the FileStream when the GZipStream is disposed. Also to the OP: Empirically, we've seen issues when you don't explicitly call .Flush on both 'zs' and 'fs' in your example before disposing. – Joe Nov 17 '11 at 01:48

1 Answers1

5

You are plumbing the pipes the wrong way. Fix:

using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite))
using (MemoryStream ms = new MemoryStream(resource))
using (GZipStream zs = new GZipStream(ms, CompressionMode.Decompress))
{
   zs.CopyTo(fs);
}
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Your solutions works. I can see what's going on: you're decompressing as the MemoryStream is read, and write the decompressed data straight to the file. I was trying to read the compressed data from the MemoryStream and decompress while writing to the file. TBH I don't see why one would work and the other wouldn't - logically they should have the same result. Thanks, Hans! – Ozzah Nov 17 '11 at 02:00