Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yet another DeflateStream decompression problem (using using and memory streams)

Firstly, I'm noticing that compressing the object requires more bytes then purely representing the object in binary form. (228 vs 166).

Secondly, I can't seem to decompress it.

Also, I can't use the nice CopyTo functionality since I don't have version 4 of the .NET framework.

What needs to go in the last DeflateStream using block?

MyClass MyObj = new MyClass();
MyObj.MyProp1 = true;
MyObj.MyProp2 = "Dee";
MyClass MyObAfterSerDeser = null;
using (MemoryStream ms = new MemoryStream())
{
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(ms, MyObj);
    byte[] prebytes = ms.ToArray(); // length 166.
    ms.SetLength(0L); 
    using(MemoryStream tmpms = new MemoryStream())
    {
        using (DeflateStream dsc = new DeflateStream(tmpms, CompressionMode.Compress))
        {
            dsc.Write(prebytes, 0, prebytes.Length);
            tmpms.WriteTo(ms); // unforunately though, just want the # of compressed bytes.
        }
    }
    byte[] cbytes = ms.ToArray();  // length 228.  Longer than uncompressed version!
    ms.SetLength(0L);

    using (MemoryStream tmpms = new MemoryStream())
    {
        tmpms.Write(cbytes, 0, cbytes.Length);
        tmpms.Position = 0;
        using (DeflateStream dsd = new DeflateStream(tmpms, CompressionMode.Decompress))
        {
            byte[] dbytes = new byte[cbytes.Length];
            dsd.Read(dbytes, 0, dbytes.Length);
            int offset = ReadAllBytesFromStream(dsd, dbytes);  // written by Mr. Skeet.
            // dsd.Write(dbytes, 0, cbytes.Length);
            // dsd.Read(dbytes, 0, dbytes.Length);
            ms.Write(dbytes, 0, offset);
        }
    }
    MyObAfterSerDeser = (MyClass)bf.Deserialize(ms);
}
like image 763
user420667 Avatar asked Aug 28 '26 11:08

user420667


1 Answers

There is no guarantee that deflate will always result in a smaller size (although it should just use a "stored/raw/undeflated" section in such cases).

The .NET deflate implementation (which is also used in the GZipStream) is known to be particular bad (although conforming) when encoding small and/or already compressed data. There are 3rd party libraries, including DotNetZip, that correct these two issues present in the .NET BCL.

When I do deflate compression (on small pieces of data) I have a "deflated" flag so the stream I store is only sometimes deflated, depending upon if the deflate was "worth it".

Happy coding.