Compressing Object in Dot Net

2020-07-28 11:30发布

问题:

I want to Compress an Object in dot net to reduce its size and then UnCompress it on in my client application.

Thanks, Mrinal Jaiswal

回答1:

I have update the code there was a problem with older version.

Here is a function which serialize and compress and viceversa.

public static byte[] SerializeAndCompress(object obj) {

    using (MemoryStream ms = new MemoryStream()) {
        using (GZipStream zs = new GZipStream(ms, CompressionMode.Compress, true)) {
            BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(zs, obj);
        }
        return ms.ToArray();
    }
}
public static object DecompressAndDeserialze(byte[] data) {

    using (MemoryStream ms = new MemoryStream(data)) {
        using (GZipStream zs = new GZipStream(ms, CompressionMode.Decompress, true)) {
            BinaryFormatter bf = new BinaryFormatter();
            return bf.Deserialize(zs);
        }
    }
}

Following is how to use it.

    [Serializable]
    class MyClass
    {
        public string Name { get; set; }
    }

    static void Main(string[] args) {
        MyClass myClassInst = new MyClass();
        myClassInst.Name = "Some Data";

        byte[] data= SerializeAndCompress(myClassInst);
        MyClass desInst = (MyClass)DecompressAndDeserialze(data);

    }

But there is a catch to compression. Remember the above example object is serialize to 153 bytes but the compress version is 266 bytes the reason is that if have small objects with less data then the gzip header information and compression header will at least take 120bytes. So if your object are big enough than compress them if they are just less 300 bytes or so its no need to compress them. You can check compression ratio and see if you object even require compression.

Another suggestion try to compress bulk of data will always give better compression over individual compress objects.



回答2:

You can always GZip it.



回答3:

I suppose you need to improve the serialization procedure, by compressing the contained data. Once I needed that in .NET, I used SoapExtensions, but you can also use httpmodule's functionality like msdn proposed:

//overriding the GetWebRequest method in the Web service proxy
protected override WebRequest GetWebRequest(Uri uri)
{
  WebRequest request = base.GetWebRequest(uri);
  request.Headers.Add("Accept-Encoding", "gzip, deflate");
  return request;
}
//overriding the GetWebResponse method in the Web service proxy
protected override WebResponse GetWebResponse(WebRequest request)
{
  //decompress the response from the Web service
  return response;
}


回答4:

Serialize it simply by adding the following above your class: (maybe take a look at: http://blog.kowalczyk.info/article/Serialization-in-C.html to fully understand how it works.)

[Serializable]
class Whatever