【问题标题】:Read length prefix before deserialize with length prefix在使用长度前缀反序列化之前读取长度前缀
【发布时间】:2015-02-20 22:49:23
【问题描述】:

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

【问题讨论】:

    标签: c# protobuf-net


    【解决方案1】:

    这在很大程度上取决于“从流中读取数据包长度”的含义。首先,数据包 在流中不存在 - 你只有:流。您可以在其中框架,而这正是*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();
    }
    

    【讨论】:

    • 我真正需要做的是从流中反序列化对象(带有一些扩展名)(这就是我使用 *WithLengthPrefix 方法的原因),同时获取它的字节长度网络统计目的。但是我不能只从流中读取第一个字节来获取对象的长度,因为在那之后我不能返回流位置以进行反序列化。理想情况下,DeserializeWithLengthPrefix 方法可以返回序列化的对象长度。但因为它不是我正在寻找另一种方式。
    • 嗨,Marc,我正在从 BinaryReader 流中读取数据,并希望使用 yield return 对序列化过程进行时间切片。我该怎么做?
    • @bartburkhardt 我不清楚为什么你会使用BinaryReader...这里不合适(请注意,流基本上是能够二进制的设备阅读 - BinaryReader 只是一个实用程序包装器,可以帮助进行一些类型转换,但如果您的数据格式不是 BinaryReader 想要的格式,则不适用)。您能否澄清“想要对序列化过程进行时间切片”的意思?
    • 我在 Unity3d 中使用它。为了保持流畅的动画,我现在使用 yield return 在游戏循环中读取一个文件。因此,如果游戏以 60fps 运行,则文件将分部分加载以具有流畅的动画效果。我从二进制格式化程序切换到 Protobuf,它的序列化速度快了 4 倍,但是当我加载 1.7mb 的文件对象时,游戏中仍然存在问题
    • @bartburkhardt k ...你是说你想做的是反序列化一些每个切片?这是一个大对象吗?还是它是子对象的集合? (或者可以这样解释)。您所描述的内容可能是可以实现的,但相当复杂,需要更多背景信息。
    猜你喜欢
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 2017-01-23
    • 2013-04-08
    • 2019-11-04
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多