I’ve discovered that the GZip compression built into C# (System.IO.Compression.GZipStream) doesn’t really do that good a job at compressing data. I heard (cannot confirm) that MS had to tread lightly around some patents which results in pretty poor compression ratios. I needed to compress some data, and compress it well, as I had a whole bunch of data files from a reporting project totalling up to 5gigs. So the GZipStream wouldn’t do.

I then tried DotNetZip which had much the same problems of low compression ratios.

Finally I stumbled across Peter Bromberg’s example of how to use the 7-Zip C# libraries (totally managed code - BIG PLUS), so here is an example project I did using it for your reference.

This is a C# / .Net console app, but the code will work the same for ASP.Net too. Basically there are two helper functions (compress / decompress) that take a byte array (byte[]) and return a byte array. Too simple! And the compression ratio is much better than the others. For my already-optimised binary data, it came to 40% of the original size.

Download MySevenZipper example project

The gist of how I came up with this is, you download the latest 7-Zip SDK, just extract the C# bits (the CS folder). Then delete the CS\7Zip\Compress\LzmaAlone folder, as it contains a Main function and a solution file and some other junk you dont need. Then go to Peter Bromberg’s helper code, download it and find the ‘SevenZipHelper.cs’ file, it’s all you need.

Then copy all these files into one 7Zip folder and include it in your C# project and use it as shown below:

// Some random text to compress, thanks to http://en.wikipedia.org/wiki/V8
string OriginalText =
@"From A V8 engine is a V engine with eight cylinders mounted on the crankcase
in two banks of four cylinders, in most cases set at a right angle to each other
but sometimes at a narrower angle, with all eight pistons driving a common crankshaft.";

// Convert the text into bytes
byte[] DataBytes = ASCIIEncoding.ASCII.GetBytes(OriginalText);
Console.WriteLine("Original data is {0} bytes", DataBytes.Length);

// Compress it
byte[] Compressed = SevenZip.Compression.LZMA.SevenZipHelper
  .Compress(DataBytes);
Console.WriteLine("Compressed data is {0} bytes", Compressed.Length);

// Decompress it
byte[] Decompressed = SevenZip.Compression.LZMA.SevenZipHelper
  .Decompress(Compressed);
Console.WriteLine("Decompressed data is {0} bytes", Decompressed.Length);

// Convert it back to text
string DecompressedText = ASCIIEncoding.ASCII.GetString(Decompressed);
Console.WriteLine("Is the decompressed text the same as the original? {0}",
  DecompressedText == OriginalText);

// Print it out
Console.WriteLine("And here is the decompressed text:");
Console.WriteLine(DecompressedText);

Thanks for reading! And if you want to get in touch, I'd love to hear from you: chris.hulbert at gmail.

Chris Hulbert

(Comp Sci, Hons - UTS)

Software Developer (Freelancer / Contractor) in Australia.

I have worked at places such as Google, Cochlear, Assembly Payments, News Corp, Fox Sports, NineMSN, FetchTV, Coles, Woolworths, Trust Bank, and Westpac, among others. If you're looking for help developing an iOS app, drop me a line!

Get in touch:
[email protected]
github.com/chrishulbert
linkedin



 Subscribe via RSS