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

发布于 2024-08-25 14:30:33 字数 424 浏览 6 评论 0原文

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

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 只是一个未初始化的实例。这是预期的行为吗?如果是,如何从流中的随机位置反序列化对象?

I'm serializing several objects into a single stream, but when i try to read them back, i can't seem to get anything but the last object:

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);

The first deserialize moves the stream to the end and postA2 contains the value of postB1, while postB2 is just an uninitialized instance. Is this expected behavior, and if so, how do you deserialize an object from a random position in a stream?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

叫嚣ゝ 2024-09-01 14:30:33

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

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

By default, protobuf (the Google spec, not proobuf-net specifically) is designed to allow you to treat consecutive messages as part of a single object - i.e. you can add fields to a message simply by concatenating, which is essentially what you are doing here. Each top-level object does not (by default) have any kind of separation from the next object.

To get it to treat them as different objects, look at the *WithLengthPrefix methods (or you can use the IEnumerable<T> versions - perhaps DeserializeItems; note also that it will apply length prefixes automatically if you give it something like a list to serialize); for example:

Essentially:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文