解密得出PIID Value产生的Unknown wire-type 6异常

来源:互联网 发布:大数据对贵州的影响 编辑:程序博客网 时间:2024/06/07 23:15

栈溢出中说的很多,但主要就是覆盖重写的时候数据格式/数据类型不一致,所以应该用FileMode方式先进行截断,然后进行反序列化的时候才不会出现Unknown wire-type 6异常。

(this is a re-post of a question that I saw in my RSS, but which was deleted by the OP. I've re-added it because I've seen this question asked several times in different places; wiki for "good form")

Suddenly, I receive a ProtoException when deserializing and the message is: unknown wire-type 6

  • What is a wire-type?
  • What are the different wire-type values and their description?
  • I suspect a field is causing the problem, how to debug this?

First thing to check:

IS THE INPUT DATA PROTOBUF DATA? If you try and parse another format (json, xml, csv, binary-formatter), or simply broken data (an "internal server error" html placeholder text page, for example), thenit won't work.




What is a wire-type?

It is a 3-bit flag that tells it (in broad terms; it is only 3 bits after all) what the next data looks like.

Each field in protocol buffers is prefixed by a header that tells it which field (number) it represents,and what type of data is coming next; this "what type of data" is essential to support the case whereunanticipated data is in the stream (for example, you've added fields to the data-type at one end), asit lets the serializer know how to read past that data (or store it for round-trip if required).


What are the different wire-type values and their description?


  • 0: variant-length integer (up to 64 bits) - base-128 encoded with the MSB indicating continuation (used as the default for integer types, including enums)
  • 1: 64-bit - 8 bytes of data (used for double, or electively forlong/ulong)
  • 2: length-prefixed - first read an integer using variant-length encoding; this tells you how many bytes of data follow (used for strings,byte[], "packed" arrays, and as the default for child objects properties / lists)
  • 3: "start group" - an alternative mechanism for encoding child objects that uses start/end tags - largely deprecated by Google, it is more expensive to skip an entire child-object field since you can't just "seek" past an unexpected object
  • 4: "end group" - twinned with 3
  • 5: 32-bit - 4 bytes of data (used for float, or electively forint/uint and other small integer types)

I suspect a field is causing the problem, how to debug this?


Are you serializing to a file? The most likely cause (in my experience) is that you have overwritten an existing file, but have not truncated it; i.e. itwas 200 bytes; you've re-written it, but with only 182 bytes. There are now 18 bytes of garbage on the end of your stream that is tripping it up. Files must be truncated when re-writing protocol buffers. You can do this withFileMode:

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

or alternatively by SetLength after writing your data:

file.SetLength(file.Position); 

Other possible cause

You are (accidentally) deserializing a stream into a different type than what was serialized. It's worth double-checking both sides of the conversation to ensure this is not happening.


0 0