Using a MemoryStream with GZipStream [Lakshan Fernando]

We’ve seen cases where our customers have run into issues when using a MemoryStream with GZip compression. The problem can be frustrating to debug and I thought I’ll blog about it in the hope that others would avoid a similar issue. The code for this looks like this;

        Byte[] compressedBuffer;

        MemoryStream stream = new MemoryStream();

        using (GZipStream zip = new GZipStream(stream, CompressionMode.Compress))

        {

            //compress data

            ...

            //Dont get the MemoryStream data before the GZipStream is closed since it doesn’t yet contain complete compressed data.

//GZipStream writes additional data including footer information when its been disposed

compressedBuffer = stream.ToArray(); //WRONG

        }

        // CORRECT CODE: call compressedBuffer = stream.ToArray() here after the GZipStream is disposed

The problem arises because the data in MemoryStream is not complete when ToArray is called before the GZipStream is closed. We will write any remaining compressed data and footer information to GZipStream when its being closed. The data in the MemoryStream is still accessible even after its been closed. Both ToArray and GetBuffer methods will return valid data after the MemoryStream has being disposed. This is not so much an issue when another stream like FileStream is used in compression since there is generally time before decompression when a file is used and its ok for the file to be re-opened when that happens.