在使用长度前缀反序列化之前读取长度前缀

时间:2015-02-18 12:42:20

标签: c# protobuf-net

protobuf-net中是否有任何方法可以从流中读取数据包长度,然后使用Serializer.DeserializeWithLengthPrefix对数据包进行反序列化?我的意思是在不将数据复制到其他流等的情况下执行这些操作。

1 个答案:

答案 0 :(得分:2)

这很大程度上依赖于“从流中读取数据包长度”的含义。首先,流中的数据包 不存在 - 你只需要:流。您可以在其中框架,这正是*WithLengthPrefix方法已经执行的。因此,如果您在两端使用*WithLengthPrefix方法,它应该已经正确读取而不会尝试过度阅读等。但是,问题中的信息不足以说明这一点。


从评论中的澄清;是的,您可以使用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();
}