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

Posted

技术标签:

【中文标题】使用 protobuf-net 反序列化当前流位置的类型【英文标题】:Deserializing a type at the current stream position with protobuf-net 【发布时间】:2010-03-14 08:29:52 【问题描述】:

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

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】:

默认,protobuf(Google 规范,不是专门的 proobuf-net)旨在让您将连续消息视为单个对象的一部分 - 即您可以简单地向消息添加字段通过连接,这基本上就是你在这里所做的。每个***对象(默认情况下)与下一个对象没有任何种分隔。

要让它将它们视为不同的对象,请查看 *WithLengthPrefix 方法(或者您可以使用 IEnumerable&lt;T&gt; 版本 - 也许是 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);

【讨论】:

正是我想要的。我没有看到 DeserializeWithLengthPrefix 做了什么。谢谢

以上是关于使用 protobuf-net 反序列化当前流位置的类型的主要内容,如果未能解决你的问题,请参考以下文章

Protobuf-net 对字节数组进行序列化/反序列化

我可以使用 Protobuf-net 对已用 Java 序列化的数据进行反序列化吗?

使用 protobuf-net 反序列化字典

使用 protobuf-net 反序列化不同的列表

为啥我不能使用 ProtoBuf-Net 正确反序列化我的对象?

使用 ProtoBuf-Net,如何(反)序列化多维数组?