You need to Close()
the ZipStream
after adding all the data you want to compress; it retains a buffer of unwritten bytes internally (even if you Flush()
) that needs to be written.
More generally, Stream
is IDisposable
, so you should also be using
each… (yes, I know that MemoryStream
isn’t going to lose any data, but if you don’t get into this habit, it will bite you with other Stream
s).
public static byte[] Compress(byte[] data)
{
using (var compressedStream = new MemoryStream())
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
{
zipStream.Write(data, 0, data.Length);
zipStream.Close();
return compressedStream.ToArray();
}
}
public static byte[] Decompress(byte[] data)
{
using(var compressedStream = new MemoryStream(data))
using(var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
using (var resultStream = new MemoryStream())
{ ... }
}
[edit : updated re comment]
Re not using
things like MemoryStream
– this is always a fun one, with lots of votes on either side of the fence: but ultimatey…
(rhetorical – we all know the answer…) How is MemoryStream
implemented? is it a byte[] (owned by .NET)? is it a memory-mapped file (owned by the OS)?
The reason you aren’t using
it is because you are letting knowledge of internal implementation details change how you code against a public API – i.e. you just broke the laws of encapsulation. The public API says: I am IDisposable
; you “own” me; therefore, it is your job to Dispose()
me when you are through.