【问题标题】:Protobuf error:Protocol message tag had invalid wire typeProtobuf 错误:协议消息标签的线路类型无效
【发布时间】:2011-05-26 12:48:34
【问题描述】:

尝试在 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文件的

谢谢

【问题讨论】:

  • (我将第二个问题合并到这个问题中)
  • 可能不是损坏的文件,而是更新的 protobuf 版本

标签: java protocol-buffers


【解决方案1】:

我非常怀疑您是否在那儿遇到了异常-我希望您在parseFrom 中得到它。你能发布完整的堆栈跟踪而不是前三行吗?

我强烈怀疑你的文件基本上是损坏的。您为应该是 binary 文件的文件提供了 .txt 扩展名这一事实有点令人怀疑……该文件实际上是什么样的?不要像这样使用parseFrom 来解析protobuf 消息的ASCII 表示。

编辑:根据评论中链接的问题,您正在尝试使用为 binary 数据设计的方法解析 text 文件。

你想使用类似的东西:

// 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();

【讨论】:

  • 非常感谢。现在它工作正常。我花了一整天但无法找到错误。非常感谢
  • 这个答案为我节省了一天。如果有人像我一样从 json 而不是 txt 解析,你可以像这样使用 JsonFormatter: JsonFormat jsonFormat = new JsonFormat(); jsonFormat.merge(targetStream, builder);其中 targetStream 是一个 InputStream(基本上是 byteArray)
【解决方案2】:

当我看到用户报告此类消息时,这几乎总是意味着他们已经损坏了文件。从.txt 开始是一个令人担忧的迹象,因为协议缓冲区是一种二进制格式,不能用文本编码表示(除非您计算 base-64 等)。

另一个常见的原因是用 less 数据覆盖文件而不修剪多余的数据。由于协议缓冲区(对于根消息)既不包含长度前缀也不包含终止符,因此将处理来自先前文件内容的任何多余数据(现在基本上是垃圾)。这是一件坏事;覆盖时必须始终修剪输出。

【讨论】:

  • @Marc GravellSO 有没有办法把这个文本文件变成二进制文件
  • 那么有没有办法将此文本文件制作为二进制文件
  • 我无法理解你所说的过度写作是什么意思,我应该怎么做才能修剪。谢谢你的直升机
  • @ravi - 啊,您使用的是辅助 text 格式(呃...为什么?) - 然后就像 Jon 指出的那样,您使用了错误的 API跨度>
猜你喜欢
  • 1970-01-01
  • 2020-06-27
  • 2015-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
  • 1970-01-01
相关资源
最近更新 更多