【问题标题】:How to Serialize/De-Serialize List<MyClass> using protobuf-net C#如何使用 protobuf-net C# 序列化/反序列化 List<MyClass>
【发布时间】:2014-04-11 12:35:59
【问题描述】:

我有一个简单的类,比如

public class Customer{
 public long Id;
 public string Name;
 ....
}

我有一个列表,我想使用 protobuf-net 对其进行序列化。请指导我简单有效的序列化和反序列化方法。

EDIT-1 我正在查看 protobuf-net 源代码提供的单元测试,它使用 2 种方式进行序列化,使用反射和模型(内部处理基于 ToString 的映射)。

我从源代码中遵循的是,我使用了与在源代码的项目文件夹 e-ProtoBufNetWithModel 中测试的相同的技术,并创建了一个 TypeModel...

public static TypeModel CreateModel()
    {
        RuntimeTypeModel model = TypeModel.Create();

        model.Add(typeof(Customer), false)
        .Add(1, "Id")
        .Add(1, "Name");

        TypeModel compiled = model.Compile();

        return compiled;
    }

问题领域

 public static Stream SerializeUsingProtobuf(IList<Customer> pSource)
    {
        var model = CreateModel();
        using (Stream memoryStream = new MemoryStream())
        {
            model.Serialize(memoryStream, pSource);
            return memoryStream;
        }

    }

TypeModel compiled = model.Compile(); 上,它引发异常 检测到重复的字段编号; 1

【问题讨论】:

标签: c# protobuf-net


【解决方案1】:

每个要序列化的字段都需要一个不同的标签(一个正整数)。在调用 Add 时尝试使用 1 和 2 而不是 1 和 1。或者更简单,只需 Add("Id", "Name");

【讨论】:

    【解决方案2】:

    https://code.google.com/p/protobuf-net/

    短版 (另见旧主页)

    序列化是一种痛苦。 protobuf-net 旨在通过最少的更改(来自可选的 .proto 架构)轻松用于现有代码,从而在各种 .NET 平台上实现快速且可移植的二进制序列化。

    它不是“碰巧在 .NET 上的协议缓冲区实现”,而是“碰巧使用协议缓冲区的 .NET 序列化程序” - 重点是熟悉 .NET 用户(例如,工作如果需要,可以在可变的、代码优先的类上)。除了常规的 protobuf 设计之外,我还添加了一系列常用的功能,以帮助满足 .NET 程序员的日常需求(继承、引用跟踪等)。

    用法很简单;在最基本的层面上,简单地从流中读取或写入流;请参阅入门:

    // write to a file
    Serializer.Serialize(outputStream, person);
    
    ...
    
    // read from a file
    var person = Serializer.Deserialize<Person>(inputStream);
    

    哦,而且速度非常快;在 CPU 和带宽方面。

    如果你想在 Visual Studio 中使用 .proto 文件,有一些 VS 工具,但你不需要——你只需编写一个类,告诉序列化程序如何使用它(最常见的是添加一个几个属性,但这取决于你),然后序列化。

    https://code.google.com/p/protobuf-net/wiki/GettingStarted

    序列化数据 由于“protocol buffers”是一种二进制格式,protobuf-net 主要基于 Stream 类;这使得可以简单地与各种实现一起使用。例如,写入文件:

    var person = new Person { ID = 12345,名称 =“弗雷德”, 地址 = 新地址 { Line1 = "平面 1", Line2 =“草地” } }; 使用 (var file = File.Create("person.bin")) { 序列化器.序列化(文件,人); }

    这会将一个 32 字节的文件写入“person.bin”。在上面可能并不明显,但 Serialize 是一种通用方法 - 该行也可以是:

      using (var file = File.Create("person.bin")) {
            Serializer.Serialize<Person>(file, person);
        }
    

    但大多数时候我们可以让编译器的泛型类型推断为我们完成工作。

    反序列化数据 我们还需要找回数据!

     Person newPerson;
        using (var file = File.OpenRead("person.bin")) {
            newPerson = Serializer.Deserialize<Person>(file);
        }
    

    这会从“person.bin”中读回数据。注意我们这次需要告诉它类型(the),否则代码非常相似。

    【讨论】:

    • 不,复制粘贴并不是真正的答案
    • @MarcGravell 是的,如果它符合他的需要,这就是一个答案。 ;) 无论如何我会加你+1
    • 我代表 stackoverflow 说“不,这让我们在版权方面处于尴尬境地”。在这种情况下,作为版权所有者,我不太可能发出删除通知 - 但是:如果您不增加任何价值,出于这两种原因,应该首选链接。
    猜你喜欢
    • 2012-11-16
    • 1970-01-01
    • 2012-04-26
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    相关资源
    最近更新 更多