为了账号安全,请及时绑定邮箱和手机立即绑定

使用Protobuf-net,我突然发现了未知电线类型的异常

使用Protobuf-net,我突然发现了未知电线类型的异常

C#
一只斗牛犬 2019-10-18 10:48:16
(这是我在RSS中看到的一个问题的重新发布,但是被OP删除了。我重新添加了它,因为我已经在不同的地方多次问过这个问题; Wiki表示“很好形成”)突然,我ProtoException在反序列化时收到一个消息,消息是:未知导线类型6什么是线型?有哪些不同的线型值及其说明?我怀疑是字段引起问题,如何调试呢?
查看完整描述

3 回答

?
UYOU

TA贡献1878条经验 获得超4个赞

首先要检查的是:


输入数据是原始数据吗?如果您尝试解析其他格式(json,xml,csv,二进制格式化程序)或仅是损坏的数据(例如,“内部服务器错误” html占位符文本页面),那么它将不起作用。


什么是线型?


它是一个3位标记,告诉它(广义而言;毕竟只有3位)下一个数据的外观。


协议缓冲区中的每个字段都以标头作为前缀,该标头告诉它表示哪个字段(数字)以及接下来要传输的数据类型。这种“什么类型的数据”对于支持流中意外数据的情况至关重要 (例如,您已在一端将字段添加到数据类型中),因为它使序列化程序知道如何读取该数据。数据(或根据需要将其存储为往返)。


有哪些不同的线型值及其说明?


0:变长整数(最多64位)-用MSB编码的base-128指示连续性(用作整数类型(包括枚举)的默认值)

1:64位-8字节数据(用于double,或可选地用于long/ ulong)

2:长度前缀-首先使用变长编码读取整数;这告诉您要跟随多少字节的数据(用于字符串byte[],“打包”数组,以及作为子对象属性/列表的默认值)

3:“开始组”-一种使用开始/结束标签对子对象进行编码的替代机制-在很大程度上已被Google弃用,跳过整个子对象字段的成本更高,因为您不能只是“寻找”一个意外的对象宾语

4:“结束组”-与3结对

5:32位-4个字节的数据(用于float,或可选地用于int/ uint和其他小整数类型)

我怀疑是字段引起问题,如何调试呢?


您要序列化到文件吗?在最有可能的原因(在我的经验)是,已覆盖现有文件,但还没有被截断它; 即是 200字节;您已经重写了它,但是只有182个字节。现在,流的末尾有18个字节的垃圾将其绊倒。重写协议缓冲区时,文件必须被截断。您可以使用FileMode:


using(var file = new FileStream(path, FileMode.Truncate)) {

    // write

}

或者SetLength 在写入数据后:


file.SetLength(file.Position);

其他可能原因


您正在(意外地)将流反序列化为与序列化的类型不同的类型。值得仔细检查对话双方,以确保不会发生这种情况。


查看完整回答
反对 回复 2019-10-18
?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

由于堆栈跟踪引用了这个StackOverflow问题,所以我想指出的是,如果(意外地)将流反序列化为与序列化的类型不同的类型,那么您也会收到此异常。因此,有必要仔细检查对话双方,以确保不会发生这种情况。


查看完整回答
反对 回复 2019-10-18
  • 3 回答
  • 0 关注
  • 632 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信