Протобуф десериализовать исключение

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

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

1 ответ

Решение

Я вручную расшифровал вашу строку и согласен с библиотекой: ваше сообщение обрезано. Я предполагаю, что это потому, что вы используете 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 с двоичными данными.

Другие вопросы по тегам