【问题标题】:C# serialize generic list<customObject> to fileC# 将通用列表<customObject> 序列化为文件
【发布时间】:2011-11-01 08:56:39
【问题描述】:

我有一个类,它包含有关图片的信息,例如文件路径、哈希值、字节。 在另一个类中,我得到了一个通用列表,我在其中放置了包含图片信息的类中的对象。

那个类看起来像这样:

[Serializable()]
    class PicInfo : ISerializable
    {
        public string fileName { get; set; }
        public string completeFileName { get; set; }
        public string filePath { get; set; }
        public byte[] hashValue { get; set; }

        public PicInfo()
        { }

        public PicInfo(SerializationInfo info, StreamingContext ctxt)
        {
            this.fileName = (string)info.GetValue("fileName", typeof(string));
            this.completeFileName = (string)info.GetValue("completeFileName", typeof(string));
            this.filePath = (string)info.GetValue("filePath", typeof(string));
            this.hashValue = (byte[])info.GetValue("hashValue", typeof(byte[]));
        }

        public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            info.AddValue("fileName", this.fileName);
            info.AddValue("completeFileName", this.completeFileName);
            info.AddValue("filePath", this.filePath);
            info.AddValue("hashValue", this.hashValue);
        }
    }

我的名单只是list&lt;picinfo&gt; pi = new list&lt;picinfo&gt;(); 序列化此列表的最简单方法是什么?

【问题讨论】:

  • 您真的应该再澄清一下您的问题。您在寻找什么序列化格式?人类可读?二进制?请提供更多信息
  • 不使用 ISerializable 也能正常工作。 .NET 可以将它们全部序列化以方便使用..?
  • 格式应该是二进制的,很抱歉没有告诉这个。
  • @mtijn 不正确;仅适用于XmlSerializer
  • @Yustme 如果你使用BinaryFormatter(我假设你是),它将是二进制的无论你是否实现ISerializable。我强烈建议不要实施ISerializable,除非你有充分的理由(但是:我也强烈建议首先不要使用BinaryFormatter;p)

标签: c# serialization generic-list


【解决方案1】:

如果你想使用BinaryFormatter(我真的不建议这样做),你可以使用:

[Serializable]
class PicInfo
{
    public string fileName { get; set; }
    public string completeFileName { get; set; }
    public string filePath { get; set; }
    public byte[] hashValue { get; set; }

    public PicInfo()  { }
}
static class Program
{
    static void Main()
    {
        List<PicInfo> pi = new List<PicInfo>();
        pi.Add(new PicInfo {fileName = "foo.bar", hashValue = new byte[] {1, 2, 3}});

        var ser = new BinaryFormatter();
        using (var ms = new MemoryStream())
        {
            ser.Serialize(ms, pi);
            var bytes = ms.ToArray();
        }
    }
}

如果您想使用XmlSerializer(可能更适合IMO),但需要byte[],那么:

public class PicInfo
{
    public string fileName { get; set; }
    public string completeFileName { get; set; }
    public string filePath { get; set; }
    public byte[] hashValue { get; set; }

    public PicInfo()  { }
}
static class Program
{
    static void Main()
    {
        List<PicInfo> pi = new List<PicInfo>();
        pi.Add(new PicInfo {fileName = "foo.bar", hashValue = new byte[] {1, 2, 3}});

        var ser = new XmlSerializer(typeof(List<PicInfo>));
        using (var ms = new MemoryStream())
        {
            ser.Serialize(ms, pi);
            var bytes = ms.ToArray();
        }
    }
}

就个人而言,我会使用 protobuf-net:

[ProtoContract]
public class PicInfo
{
    [ProtoMember(1)]public string fileName { get; set; }
    [ProtoMember(2)]public string completeFileName { get; set; }
    [ProtoMember(3)]public string filePath { get; set; }
    [ProtoMember(4)]public byte[] hashValue { get; set; }

    public PicInfo()  { }
}
static class Program
{
    static void Main()
    {
        List<PicInfo> pi = new List<PicInfo>();
        pi.Add(new PicInfo {fileName = "foo.bar", hashValue = new byte[] {1, 2, 3}});

        using (var ms = new MemoryStream())
        {
            Serializer.Serialize(ms, pi);
            var bytes = ms.ToArray();
        }
    }
}

尺寸:

  • BinaryFormatter: 488 字节
  • XmlSerializer:251 字节
  • protobuf-net:16 个字节

【讨论】:

  • 你好,它不应该是一个xml文件,只是一个txt文件。顺便说一句,你能解释一下为什么不是 binaryformatter 吗?
  • @Yustme 很少有序列化程序会写“只是一个 txt 文件”——它们会被格式化;也许是定制的二进制文件,也许是 xml,也许是 json - 但绝不是“只是一个 txt 文件”(除非你将 xml 或 json 算作“只是文本”)。回复BinaryFormatter:很多原因;它有版本不容忍的习惯,它不是跨平台的(例如,即使在 Silverlight 上也无用),它很慢,并且输出超重。即使是无形的更改,例如使某些东西成为自动实现的属性,也会破坏它。哦,它往往会通过事件吸入不需要的对象。
  • 我明白了。我还有一个问题,我可以再次反序列化吗?
  • @Yustme 绝对! (顺便说一句,如果您正在写入磁盘,您可以在这里用FileStream 轻松替换MemoryStream)。使用MemoryStream 只需将.Position 设置回0。使用FileStream 您只需File.OpenRead(path) 即可获取流。
猜你喜欢
  • 1970-01-01
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多