Ошибка Protobuf: у тега сообщения протокола был неверный тип провода - PullRequest
9 голосов
/ 26 мая 2011

У меня возникает следующая ошибка при попытке прочитать сообщение в Java

Exception in thread "main" com.google.protobuf.InvalidProtocolBufferException: Protocol message tag had invalid wire type.
    at com.google.protobuf.InvalidProtocolBufferException.invalidWireType(InvalidProtocolBufferException.java:78)
    at com.google.protobuf.UnknownFieldSet$Builder.mergeFieldFrom(UnknownFieldSet.java:498)
    at com.google.protobuf.GeneratedMessage$Builder.parseUnknownField(GeneratedMessage.java:438)

FileInputStream fis = new FileInputStream("F:/Newfolder/sample_message.txt");
Nt nlc = Nt.parseFrom(fis);

if(nlc.hasMessageId())
{
    System.out.println("MessageId: "+nta2sse.getMessageId());
}

Я получаю исключение на if(nlc.hasMessageId())


Вот трассировка полного стека.

Exception in thread "main" com.google.protobuf.InvalidProtocolBufferException: Protocol message tag had invalid wire type.
    at com.google.protobuf.InvalidProtocolBufferException.invalidWireType(InvalidProtocolBufferException.java:78)
    at com.google.protobuf.UnknownFieldSet$Builder.mergeFieldFrom(UnknownFieldSet.java:498)
    at com.google.protobuf.GeneratedMessage$Builder.parseUnknownField(GeneratedMessage.java:438)
    at com.soeasy.aanta.nta.sse.NtaSse$Nta2Sse$Builder.mergeFrom(NtaSse.java:523)
    at com.soeasy.aanta.nta.sse.NtaSse$Nta2Sse$Builder.mergeFrom(NtaSse.java:1)
    at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:1)
    at com.google.protobuf.AbstractMessageLite$Builder.mergeFrom(AbstractMessageLite.java:212)
    at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:746)
    at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:1)
    at com.google.protobuf.AbstractMessageLite$Builder.mergeDelimitedFrom(AbstractMessageLite.java:282)
    at com.google.protobuf.AbstractMessage$Builder.mergeDelimitedFrom(AbstractMessage.java:760)
    at com.google.protobuf.AbstractMessageLite$Builder.mergeDelimitedFrom(AbstractMessageLite.java:288)
    at com.google.protobuf.AbstractMessage$Builder.mergeDelimitedFrom(AbstractMessage.java:752)
    at com.soeasy.aanta.nta.sse.NtaSse$Nta2Sse.parseDelimitedFrom(NtaSse.java:338)
    at com.soeasy.aanta.nta.sse.NtaSseServer.main(NtaSseServer.java:60)

, а образец _message.txt имеет следующее:

message_id: 1
batch_meas_update {
  device_update {
    unique_device_id {
      device_type: ME
      device_id: 161
    }
    meas_update {
      override_status: OVERRIDE_INACTIVE
      bad_data_status: GOOD_DATA
      scada_status: SCADA_ACTIVE
      weight: 1.0
      value: 406.596
    }
  }
}

В соответствии с .proto файлом

Спасибо

Ответы [ 2 ]

17 голосов
/ 26 мая 2011

Я очень сомневаюсь, что вы получите исключение - я ожидаю, что вы получите его в parseFrom.Не могли бы вы опубликовать полную трассировку стека вместо первых трех строк?

Я сильно подозреваю, что у вас в основном поврежденный файл.Тот факт, что вы дали расширение .txt для того, что должно быть бинарным файлом, несколько подозрительно ... как этот файл на самом деле выглядит?Вы не используете parseFrom таким образом, чтобы проанализировать ASCII-представление сообщения protobuf. * ​​1010 *

РЕДАКТИРОВАТЬ: Согласно вопросу, связанному в комментарии, вы пытаетесь проанализировать текст файл с использованием метода, предназначенного для двоичных данных.

Вы хотите использовать что-то вроде:

// Use the normal try/finally for closing reliably
InputStreamReader reader = new InputStreamReader(fis, "ASCII");

Nt.Builder builder = Nt.newBuilder();
TextFormat.merge(reader, builder);
Nt nt = builder.build();
2 голосов
/ 26 мая 2011

Когда я вижу, что пользователи сообщают об этом типе сообщения, это почти всегда означает, что они повредили файл. Начало с .txt является тревожным признаком, поскольку буферы протокола - это двоичный формат, который не может быть представлен в текстовой кодировке (если не считать base-64 и т. Д.).

Другая распространенная причина этого - перезапись файла с меньше данными и отсутствие обрезки излишков. Поскольку буферы протокола не включают (для корневого сообщения) ни префикс длины, ни терминатор, любые лишние данные (по существу, мусор сейчас) из предыдущего содержимого файла будут обработаны. Это плохо; Вы всегда должны обрезать свои выводы при перезаписи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...