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);
}
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.
You can initialize memorystream with bytes already like this (no need to write & position):
Code inside is what CopyTo does in .NET 4.0
MemoryStream output = new MemoryStream();
try
{
using (MemoryStream ms = new MemoryStream(cbytes))
using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress, true)) {
int num;
byte[] buffer = new byte[100];
while ((num = ds.Read(buffer, 0, buffer.Length)) != 0)
{
output.Write(buffer, 0, num);
}
}
MyObAfterSerDeser = (MyClass)bf.Deserialize(output);
}
finally
{
output.Dispose();
}
I got this code for a reason (notice dispose) I believe, I remember it was not working when I was trying to Dispose it by means of using output
instead which definately would look cooler.
精彩评论