Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

//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?

like image 235
makerofthings7 Avatar asked Sep 15 '10 22:09

makerofthings7


People also ask

What is GZipStream?

Gzip is a file format and software application used on Unix and Unix-like systems to compress HTTP content before it's served to a client.

What is MemoryStream io?

MemoryStream encapsulates data stored as an unsigned byte array. The encapsulated data is directly accessible in memory. Memory streams can reduce the need for temporary buffers and files in an application. The current position of a stream is the position at which the next read or write operation takes place.


1 Answers

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); 
like image 129
Timwi Avatar answered Sep 24 '22 00:09

Timwi