【问题标题】:How to append object to a file while serializing using c# protobuf-net?如何在使用 c# protobuf-net 进行序列化时将对象附加到文件中?
【发布时间】:2013-03-07 07:45:13
【问题描述】:

我得到了一个将对象序列化为文件的 Protobuf-net 源代码。

var person = new Person {
        Id = 12345, Name = "Fred",
        Address = new Address {
            Line1 = "Flat 1",
            Line2 = "The Meadows"
        }
    };
    using (var file = File.Create("person.bin")) {
        ProtoBuf.Serializer.Serialize(file, person);
    }

但假设我有两个要序列化为单个文件的 Person 实例。我该怎么做?

【问题讨论】:

标签: c# file serialization protobuf-net


【解决方案1】:

protobuf,在纯粹意义上,除了文件末尾之外没有任何“终止符”(这样可以简单地通过连接 blob 来合并/组合对象)。

但是,我们可以注入自己的标记,例如通过在每个对象前面加上后面的数据长度。

protobuf-net 通过公开SerializeWithLengthPrefix 方法来解决这个问题。有多种方法可以从中反序列化,但最简单的是DeserializeItems,它依次为您提供对象的流式序列(从迭代器中的流中延迟假脱机——因此它非常适合非常大的序列)。

有关信息,您可以查看它是如何实现的:如果您使用PrefixStyle.Base128 和一个正数fieldNumber,那么在线这看起来就像您有一个包装器对象一样喜欢:

[ProtoContract]
public class DoesNotExist {
    [ProtoMember({fieldNumber})]
    public List<Person> People {get;set;}
}

主要区别在于不存在实际的 DoesNotExist 类型/实例,也没有创建 List&lt;T&gt; - 您只需获得 Person 实例。

【讨论】:

  • Marc 你能回答一下 Serializer.SerializeWithLengthPrefix(s, command1, PrefixStyle.Base128, 0) 中字段编号(最后一个参数)(值=0)的作用是什么;
  • @Rezoan 这主要适用于使用Base128 前缀时;如果提供了正数,则前缀的写入方式使整个复合流自身成为有效的 protobuf 流,如 DoesNotExist 示例所示。一个有趣的用途是它允许您将异构对象写入同一流并按顺序删除它们 - 即您可以编写 PersonOrderPersonPerson,然后一个Address。您需要使用非泛型 API 和类型解析器将这些从流中移除,但对于 ...
  • @Rezoan ...诸如基于消息的套接字或 RPC;每个操作可以有不同的字段编号,您可以单独处理。我个人总是喜欢包含一个字段编号只是因为我喜欢让整个流都是有效的 protobuf
  • 谢谢。我会尽快回复你另一个问题。 =D
  • 只是为了清楚我在问一个问题@Marc。如果我使用 c# protbuf-net 将此人对象序列化到文件中。是否可以使用 c++ Google 的协议缓冲区轻松反序列化?
猜你喜欢
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-26
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
  • 2011-09-11
相关资源
最近更新 更多