A colleague asked me this morning if I already had a code snippet that compressed and decompressed byte arrays that he could make use of. He needed it to compress a variable before passing it as an argument to a WCF call, and decompress in the service itself. I’ve never made use of the System.IO.Compression namespace (I’d always used SharpZipLib), so I thought this would be a quick and useful experiment.
After referencing the local MSDN and then the customary 30 second google, I decided I’d make my own, better, wheel :) I’m still convinced it’s less verbose than the first ten results I looked at, by the way.
The compress part was easy enough (and follows the same logic as just about every example I found). What I couldn’t understand was why everyone implemented long-winded decompress routines. The answer to that question (found in MSDN) is that the Length property of the DeflateStream is not implemented and always throws an exception, meaning that you can’t determine the length of the byte array you’ll need.
Here’s my quick-and-easy solution to the problem:
Expand Code public static class CompressionUtils
{
const int BUFFERSIZE = 1024;
public static byte[] Compress(byte[] data)
{
var memoryStream = new MemoryStream();
var deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress);
deflateStream.Write(data, 0, data.Length);
deflateStream.Flush();
deflateStream.Close();
return memoryStream.ToArray();
}
public static byte[] Decompress(byte[] data)
{
var buffer = new byte[BUFFERSIZE];
var returnVal = new List<byte>();
var deflateStream = new DeflateStream(new MemoryStream(data), CompressionMode.Decompress);
int count;
while ((count = deflateStream.Read(buffer, 0, BUFFERSIZE)) > 0)
{
if (count != BUFFERSIZE)
{
var tmpBuffer = new byte[count];
Array.Copy(buffer, tmpBuffer, count);
returnVal.AddRange(tmpBuffer);
}
else
returnVal.AddRange(buffer);
}
return returnVal.ToArray();
}
}