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.
//Compress
System.IO.MemoryStream outStream = new System.IO.MemoryStream();
GZipStream tinyStream = new GZipStream(outStream, CompressionMode.Compress);
mStream.Position = 0;
mStream.CopyTo(tinyStream);
//Decompress
outStream.Position = 0;
GZipStream bigStream = new GZipStream(outStream, CompressionMode.Decompress);
System.IO.MemoryStream bigStreamOut = new System.IO.MemoryStream();
bigStream.CopyTo(bigStreamOut);
//Results:
//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)))
mStream.CopyTo(tinyStream);
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())
{
bigStream.CopyTo(bigStreamOut);
output = Encoding.UTF8.GetString(bigStreamOut.ToArray());
}
// “output” now contains the uncompressed string.
Console.WriteLine(output);