Протобуф десериализовать исключение - PullRequest
0 голосов
/ 27 августа 2018

Попытка десериализации сообщения с использованием protobuf в Java и получение следующего исключения.

Причина: com.google.protobuf.InvalidProtocolBufferException: при синтаксическом анализе сообщения протокола неожиданно завершился ввод в середине поля. Это может означать, что входные данные были усечены, или что внедренное сообщение неправильно указало свою длину. на com.google.protobuf.InvalidProtocolBufferException.truncatedMessage (InvalidProtocolBufferException.java:86) на com.google.protobuf.CodedInputStream $ ArrayDecoder.readRawLittleEndian64 (CodedInputStream.java:1179) на com.google.protobuf.CodedInputStream $ ArrayDecoder.readFixed64 (CodedInputStream.java:791) на com.google.protobuf.UnknownFieldSet $ ​​Builder.mergeFieldFrom (UnknownFieldSet.java:534) на com.google.protobuf.GeneratedMessageV3.parseUnknownFieldProto3 (GeneratedMessageV3.java:305)

1 Ответ

0 голосов
/ 28 августа 2018

Я вручную расшифровал вашу строку и согласен с библиотекой: ваше сообщение обрезано. Я предполагаю , что это потому, что вы используете API на основе строк, и в данных есть нулевой байт - многие текстовые API видят нулевой байт (NUL в терминах ASCII) означать конец строки.

Вот разбивка:

\n=10=field 1, length prefix - I'm assuming this is a string
\x14=20
"id:article:v1:964000"
(22 bytes used for field 1)

\x12=18=field 2, length prefix - I'm assuming this is a sub-messssage
$=36
  \n=10=field 1, length prefix - I'm assuming this is a string
  \x10=16
  "predicted_topics"
  (18 bytes used for field 2.1)

  \x12=18=field 2, length prefix - I'm assuming this is a string
  \x06=6
  "IS/biz"
  (8 bytes used for field 2.2)

  \x1a=26=field 3, length prefix - I'm assuming this is "bytes"
  \x08=8
    \xf0
    l
    \x8f
    \xde
    p
    \x9f
    \xe4

    (unexpected EOF)

в конце мы пытаемся декодировать 8 байтов самого внутреннего сообщения, и у нас осталось только 7 байтов. Я знаю, что это не дополнительное сообщение, потому что это приведет к неверному тегу, и он не будет выглядеть как UTF-8, поэтому я предполагаю, что это поле bytes (но, честно говоря, это не так Дело в том, что нам нужно 8 байт, а у нас только 7).

Я предполагаю, что последний байт в поле bytes был равен нулю; если мы предположим пропущенный \x00 в конце, то поле 2.3 будет 10 байтов, и мы учли 18 + 8 + 10 = 36 байтов, что сделает под-сообщение (поле 2) завершенным. Вполне может быть больше пропущенных данных после внешнего дополнительного сообщения - я не могу знать.

Итак: убедитесь, что вы не используете текстовые API с двоичными данными.

...