代码之家  ›  专栏  ›  技术社区  ›  Arne Claassen

用protobuf net反序列化当前流位置的类型

  •  7
  • Arne Claassen  · 技术社区  · 16 年前

    我正在将多个对象序列化为一个流,但是当我试图读回它们时,除了最后一个对象,我似乎什么也得不到:

    ProtoBuf.Serializer.Serialize(stream, postA1);
    ProtoBuf.Serializer.Serialize(stream, postB1);
    stream.Position = 0;
    var postA2 = ProtoBuf.Serializer.Deserialize<Post>(stream);
    var postB2 = ProtoBuf.Serializer.Deserialize<Post>(stream);
    

    第一个反序列化将流移动到末尾,postA2包含postB1的值,而postB2只是一个未初始化的实例。这是预期的行为吗?如果是,如何从流中的随机位置反序列化对象?

    1 回复  |  直到 13 年前
        1
  •  8
  •   Marc Gravell    16 年前

    通过 违约 protobuf(google spec,而不是proobuf net)的设计允许您将连续的消息视为单个对象的一部分,也就是说,您可以通过连接向消息添加字段,这基本上就是您在这里所做的。每个顶级对象(默认情况下)没有 任何 与下一个对象的分离。

    要让它将它们视为不同的对象,请查看 *WithLengthPrefix 方法(或者您可以使用 IEnumerable<T> 版本-可能 DeserializeItems ;还请注意,如果您为其提供类似要序列化的列表的内容,它将自动应用长度前缀;例如:

    基本上:

    Serializer.SerializeWithLengthPrefix(stream, postA1, PrefixStyle.Base128, 1);
    Serializer.SerializeWithLengthPrefix(stream, postB1, PrefixStyle.Base128, 1);
    stream.Position = 0;
    var postA2 = Serializer.DeserializeWithLengthPrefix<Post>(stream,
        PrefixStyle.Base128, 1);
    var postB2 = Serializer.DeserializeWithLengthPrefix<Post>(stream,
        PrefixStyle.Base128, 1);