【问题标题】:c# Binary Serialization output sizec#二进制序列化输出大小
【发布时间】:2014-06-05 14:31:31
【问题描述】:

BinarySerializer 的输出字符串似乎太长。即使我将类的属性名称缩短为单个字符长度,它也不会改变。

这是类文件:

using System;

namespace Models.Accounts
{
    /// <summary>
    /// PasswordResetRequest class
    /// model of a password reset request
    /// </summary>
    [Serializable]
    public class PRR
    {
        /// <summary>
        /// request id
        /// </summary>
        public string I { get; set; }

        /// <summary>
        /// time request received
        /// </summary>
        public DateTime T { get; set; }

        /// <summary>
        /// application to which the password belongs
        /// </summary>
        public string A { get; set; }

        /// <summary>
        /// username whose password needs to be reset
        /// </summary>
        public string U { get; set; }

        /// <summary>
        /// token (guid)
        /// </summary>
        public Guid G { get; set; }

        /// <summary>
        /// token used
        /// </summary>
        public bool D { get; set; }

        /// <summary>
        /// client ip
        /// </summary>
        public string C { get; set; }
    }
}

我正在使用this SO link 进行序列化。当我将序列化程序用作

        PRR request = new PRR();
        request.U = "someusername";
        request.G = Guid.NewGuid();

        string searlizedRequest = SingletonCommon.Instance.SerializeObject(request);

searlizedRequest 的值很长,例如 AAEAAAD/////AQAAAAAAAAAMAgAAAEFMSVQuTW9kZWxzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAUBAAAAF0xJVC5Nb2RlbHMuQWNjb3VudHMuUFJSBwAAABI8ST5rX19CYWNraW5nRmllbGQSPFQ+a19fQmFja2luZ0ZpZWxkEjxBPmtfX0JhY2tpbmdGaWVsZBI8VT5rX19CYWNraW5nRmllbGQSPEc+a19fQmFja2luZ0ZpZWxkEjxEPmtfX0JhY2tpbmdGaWVsZBI8Qz5rX19CYWNraW5nRmllbGQBAAEBAwABDQtTeXN0ZW0uR3VpZAECAAAACgAAAAAAAAAACgYDAAAADHNvbWV1c2VybmFtZQT8////C1N5c3RlbS5HdWlkCwAAAAJfYQJfYgJfYwJfZAJfZQJfZgJfZwJfaAJfaQJfagJfawAAAAAAAAAAAAAACAcHAgICAgICAgL20za6r7D0QbKWb7tG1cjSAAoL

我可以使用任何输出较短的格式化程序或我可以尝试的其他任何东西,因为这个字符串将成为电子邮件中发送的链接的一部分。

【问题讨论】:

  • 如果你想要一个小的结果,请改用 protobuf-net
  • 我会将这些数据放入数据库中,然后向用户发送一个小密钥以获取该信息。
  • 如果您只需要 any 序列化,请使用XmlSerializer。您可以使用属性来控制它,并且文件可以由人编辑/查看(xml 很容易理解)。如果您需要最小大小,那么您必须使用二进制序列化:BinarySerializerprotobuf(最快、最小、人类无法查看/可编辑,并且需要使用第三方库,尽管得到了很好的支持)。如果您的目标是通过 ascii-text 通道传输序列化对象,那么为什么不使用专门设计的json
  • @jgauffin 感谢 - 现在尝试 protobuf-net(尽管对 .net 的持续支持持怀疑态度)。 usr - 好主意 - 谢谢你也会尝试 Sinatr - 不能使用 xml 或 json,因为这是一个密码重置链接,它将发送到用户的电子邮件。不应该容易解码
  • 将属性转换为字段并为某些字段使用[NonSerializable] 属性,它将大小减少了近40%。现在还不错

标签: c# serialization


【解决方案1】:

也许您可以尝试GZipStream 在写入文件时压缩输出以具有最小大小

public static void SetCompressed<T>(T data,string name) 
{
    BinaryFormatter bf;
    using(FileStream fileStream = new FileStream(name+ ".object", FileMode.Create, FileAccess.Write))
    using(GZipStream compressionStream = new GZipStream(fileStream, CompressionMode.Compress))
    {
        bf.Serialize(compressionStream, data);
    }
}

public static T GetCompressed<T>(string name) 
{
    BinaryFormatter bf;
    T Tobject;
    using(FileStream fileStream = new FileStream(name + ".object", FileMode.Open, FileAccess.Read))
    using(GZipStream compressionStream = new GZipStream(fileStream, CompressionMode.Decompress))
    {
        Tobject = (T)bf.Deserialize(compressionStream);
    }

    return Tobject;
}

上面的代码使用BinaryFormatterFileStreamGZipStream 来序列化任何对象。 GZipStream 会在一定程度上压缩输出 *.object 文件。

HACK:可以用7-Zip打开*.object文件,查看里面的序列化内容。

【讨论】:

  • 最终实现了@usr 评论。
  • 反对Base64的情况是它首先将字符串编码为UTF-8,然后将生成的字节序列编码为Base64。所以会增加30 -33%。
猜你喜欢
  • 2016-07-27
  • 2018-06-06
  • 2017-10-18
  • 1970-01-01
  • 2010-12-17
  • 2015-09-17
  • 2016-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多