7Zip (LZMA) In-Memory Compression with C#

Shows a simple C# SevenZip.Compression.Lzma.SevenZipHelper class to enable high-compression of in-memory objects with C#. Adds a new 7Zip format LZMA Cookie Compression class to the previously published CookieCompression utility.

"The difference between a violin and a viola is that a viola burns longer." - Victor Borge

Many developers are familiar with 7-Zip and use it as an alternative to Winzip or Winrar. I use the Windows distribution of 7Zip frequently because of the higher compression ratios it provides, with an excellent balance between speed and high compression with the default settings.

However I would venture to guess that most developers are unaware that Igor Pavlov, the primary developer of SevenZip, provides a full SDK that includes his LZMA source code in several languages, including one in C#. 

The C# code in the SDK is designed to be used in an executable with a command - line interface. However, by recompiling this to a class library, removing the command line parser classes, and adding a simple SevenZipHelper class that uses the default property settings, we can get a very handy and powerful class library for in-memory compression tasks.

Some facts on LZMA (7Zip) Compression:

  • Average compression ratio of LZMA is about 30% better than that of gzip, and 15% better than that of bzip2.
  • Decompression speed is only little slower than that of gzip, being two to five times faster than bzip2.
  • In fast mode, 7Zip compresses faster than bzip2 with a comparable compression ratio.
  • Achieving the best compression ratios takes four to even twelve times longer than with bzip2. However. this doesn't affect decompressing speed.


To illustrate the usefulness of this approach, I took the code from a previous article on compressing Http Cookies, and added another CompressedCookie class to it in which I use the 7zip library instead of the default System.IO.Compression deflate mode classes. With LZMA compression (the default for 7Zip), we can get a huge increase in the amount of data that can be stored in the 4,000 byte allowable maximum size for a cookie.

The downloadable Visual Studio 2005 Solution below includes the SevenZip C# LZMA classes, my SevenZipHelper "wrapper class", and a reconstructed CompressedCookies Web application illustrating it's use.

Using my "Helper" class is utterly simple:

The static Compress Method:

byte[] SevenZip.Compression.LZMA.SevenZipHelper.Compress( byte[] )

The static Decompress Method:

byte[] SevenZip.Compression.LZMA.SevenZipHelper.Decompress( byte[] )

I don't think it could be made much simpler!

The new LZMA Cookie Compression class:

using System.Text;
using System.Web;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using SevenZip.Compression.LZMA;
namespace CompressedCookies
{
    public static class CpCookiesLzma
    {
        public static int Set(string cookieName, object cookieValue, DateTime expirationDate)
        {
            int siz = 0;
            try
            {
                BinaryFormatter bf = new BinaryFormatter();
                MemoryStream ms = new MemoryStream();
                bf.Serialize(ms, cookieValue);
                byte[] inbyt = ms.ToArray();
                byte[] b = SevenZip.Compression.LZMA.SevenZipHelper.Compress(inbyt);
                string sCookieVal = Convert.ToBase64String(b);
                HttpCookie cook = new HttpCookie(cookieName);
                cook.Value  = sCookieVal;
                siz = sCookieVal.Length;
                cook.Expires = expirationDate;
                HttpContext.Current.Response.Cookies.Add(cook);                 
            }
            catch 
            {
                
                throw ;
            }
            return siz;
        }

        public static object Get(string cookieName)
        {
            object retval = null;
            try
            {
                byte[] bytCook = Convert.FromBase64String(HttpContext.Current.Request.Cookies[cookieName].Value);

                byte[] outByt = SevenZip.Compression.LZMA.SevenZipHelper.Decompress(bytCook);
                
             
                MemoryStream outMs = new MemoryStream(outByt);
                outMs.Seek(0, 0);
                BinaryFormatter bf = new BinaryFormatter();                
                retval = (object)bf.Deserialize(outMs, null);
            }
            catch(Exception ex)
            {                
                throw ex;
            }
            return retval;
        }

        public static bool Delete(string cookieName)
        {
            bool retval = true;
            try
            {
                HttpContext.Current.Request.Cookies[cookieName].Expires = DateTime.Now.AddDays(-365);
            }
            catch
            {
                retval = false;
            }
             return retval;
        }

         
    }
}
The download below includes the LZMA (7Zip) C# class library project, which includes my SevenZipHelper class, the Compressed Cookies class library project with the addition of  the CpCookieLzma class with 7Zip, and a web application that illustrates it's use for compressed cookie operation. Of course, the 7Zip library can be used for any general compression need.

NOTE: If you get any "out of memory" errors using this, try reducing the size of the dictionary in the SevenZipHelper class (e.g. <<21 instead of << 23).


Download the Visual Studio 2005 Solution accompanying this article.
By Peter Bromberg   Popularity  (52422 Views)