将类转换为没有任何值的字节数组已经包含了我的256个可用字节的220个字节

时间:2012-10-17 10:40:49

标签: c# compression gzip bytearray binaryformatter

我目前正致力于将类UsageData保存到字节数组并将其存储在硬件密钥上。此硬件密钥为用户数据保留了最多256个字节数。目前,我的带有属性的填充类大小约为640字节,已经压缩。现在我开始创建一个没有任何属性/ fiels的临时类UsageDataTemp。我运行一个测试,看看没有任何值的字节数组有多大,并且它已经有220字节的大小,只剩下36个字节来填充。

    [Serializable]
    public class UsageDataTemp
    {
        public byte[] ToByteArray()
        {
            var formatter = new BinaryFormatter();
            using (var stream = new MemoryStream())
            {
                //original serialization is 684 bytes long, compress it with the gzipstream
                using (var compressionStream = new GZipStream(stream, CompressionMode.Compress))
                {
                    formatter.Serialize(compressionStream, this);
                    compressionStream.Flush();
                    return stream.ToArray();
                }
            }
        }
    }

为什么这种情况是没有任何值的空类已经需要220个字节来保存自己。有没有办法进一步压缩字节数组。或者我是否需要开始制作自己的BinaryFormatter

3 个答案:

答案 0 :(得分:2)

你没有告诉序列化器/反序列化器他们正在处理什么类型的对象 - 你可以传递任何东西,他们“应该”工作。

这意味着某些类型信息必须存储在二进制流中,以便计算出反序列化的对象类型。这很容易(我认为)占220字节的开销。


如果每个字节都重要,那么是的,您应该编写自己的代码,将您感兴趣的数据转换为最小的表示形式,而不是使用二进制序列化器等通用机制。

答案 1 :(得分:1)

  

为什么这种情况是没有任何值的空类已经需要220个字节来保存自己?

为什么要问你能找到什么?此代码已产生33个字节:

FileStream fs = new FileStream("Serialized.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, "FooString");

因为序列化的次数多于字符串本身。如果序列化对象,则其类定义(以及它所在的程序集)也将被序列化。序列化此类的实例:

[Serializable]
class Foo
{
    public String FooString { get; set; }
}

成本为166字节,而FooString属性包含与之前序列化的原始字符串相同的数据。

所以:编写自己的序列化(或:加载/保存)逻辑。您是读取和写入该数据的人,因此您可以在空间中为特定属性分配特定字节。

答案 2 :(得分:0)

您无需序列化您的结构。您只需将字节存储在硬件密钥中即可。您可以使用Object Factory模式实现某些内容,在给定256字节数组构建UsageData对象的情况下,以及从UsageData对象获取256字节数组的内容。