LamonteCristo LamonteCristo - 1 month ago 11x
C# Question

How do I use GZipStream with System.IO.MemoryStream?

I am having an issue with this test function where I take an in memory string, compress it, and decompress it. The compression works great, but I can't seem to get the decompression to work.

System.IO.MemoryStream outStream = new System.IO.MemoryStream();
GZipStream tinyStream = new GZipStream(outStream, CompressionMode.Compress);
mStream.Position = 0;

outStream.Position = 0;
GZipStream bigStream = new GZipStream(outStream, CompressionMode.Decompress);
System.IO.MemoryStream bigStreamOut = new System.IO.MemoryStream();

//bigStreamOut.Length == 0
//outStream.Position == the end of the stream.

I believe that bigStream out should at least have data in it, especially if my source stream (outStream) is being read. is this a MSFT bug or mine?


What happens in your code is that you keep opening streams, but you never close them.

  • In line 2, you create a GZipStream. This stream will not write anything to the underlying stream until it feels it’s the right time. You can tell it to by closing it.

  • However, if you close it, it will close the underlying stream (outStream) too. Therefore you can’t use mStream.Position = 0 on it.

You should always use using to ensure that all your streams get closed. Here is a variation on your code that works.

var inputString = "“ ... ”";
byte[] compressed;
string output;

using (var outStream = new MemoryStream())
    using (var tinyStream = new GZipStream(outStream, CompressionMode.Compress))
    using (var mStream = new MemoryStream(Encoding.UTF8.GetBytes(inputString)))

    compressed = outStream.ToArray();

// “compressed” now contains the compressed string.
// Also, all the streams are closed and the above is a self-contained operation.

using (var inStream = new MemoryStream(compressed))
using (var bigStream = new GZipStream(inStream, CompressionMode.Decompress))
using (var bigStreamOut = new MemoryStream())
    output = Encoding.UTF8.GetString(bigStreamOut.ToArray());

// “output” now contains the uncompressed string.