【发布时间】:2015-02-20 22:49:23
【问题描述】:
protobuf-net 中是否有任何方法可以从流中读取数据包长度,然后使用 Serializer.DeserializeWithLengthPrefix 反序列化数据包?我的意思是在不将数据复制到其他流等的情况下执行这些操作。
【问题讨论】:
标签: c# protobuf-net
protobuf-net 中是否有任何方法可以从流中读取数据包长度,然后使用 Serializer.DeserializeWithLengthPrefix 反序列化数据包?我的意思是在不将数据复制到其他流等的情况下执行这些操作。
【问题讨论】:
标签: c# protobuf-net
这在很大程度上取决于“从流中读取数据包长度”的含义。首先,数据包 在流中不存在 - 你只有:流。您可以在其中框架,而这正是*WithLengthPrefix 方法已经在做的。因此,如果您在两端使用*WithLengthPrefix 方法,它应该已经正确读取而不会尝试过度读取等。但是,问题中没有足够的信息来说明更多内容。
来自 cmets 中的说明;是的,您可以使用Serializer.TryReadLengthPrefix 手动读取前缀 - 然后创建一个长度限制的阅读器;如果是同步代码,例如:
while(Serializer.TryReadLengthPrefix(stream, style, out length))
{
using(var reader = new ProtoReader(stream, model, ctx, length))
{
var obj = mode.Deserialize(reader, null, type);
// ...
}
}
然而,在异步 IO 中,代码变得要复杂得多;首先你需要缓冲,直到你知道你有足够的帧头;然后你需要继续读取和缓冲,直到你有帧的数据。您的基本异步循环将更像:
EndRead() {
AppendNewData();
bool consumed = false;
while(HaveFrameHeaderInBuffer() && HavePayloadInBuffer()) {
ProcessFrame();
consumed = true;
}
if(consumed) DiscardConsumedDataAndShiftLeftoverUnusedData();
BeginRead();
}
【讨论】:
BinaryReader...这里不合适(请注意,流基本上是能够二进制的设备阅读 - BinaryReader 只是一个实用程序包装器,可以帮助进行一些类型转换,但如果您的数据格式不是 BinaryReader 想要的格式,则不适用)。您能否澄清“想要对序列化过程进行时间切片”的意思?