google的协议缓冲区从c#到java - 协议消息标记的线路类型无效

时间:2012-12-24 10:17:51

标签: c# java exception protocol-buffers

我在C#中创建一个流并尝试在java中读取它,但是我收到错误:“协议消息标记的线路类型无效。”当我在我的java代码中读取它时在c#中创建的对象。

详细信息: 我从一个相同的.proto文件(见下文)开始创建相应的.java文件和.cs文件(使用protoc for java版本编译“protobuf-2.4.1”和protobuf-csharp-port-2.4.1.473 c#的完整二进制文件。 我成功创建了addressbook.java和addressbook.cs。

该对象在c#中创建,并使用以下c#代码写入文件:

[...]
byte[] bytes;

        //Create a builder to start building a message
        Person.Builder newContact = Person.CreateBuilder();

        //Set the primitive properties
        newContact.SetId(1)
                  .SetName("Foo")
                  .SetEmail("foo@bar");

        //Now add an item to a list (repeating) field
        newContact.AddPhone(
            //Create the child message inline
            Person.Types.PhoneNumber.CreateBuilder().SetNumber("555-1212").Build()
            );

        //Now build the final message:
        Person person = newContact.Build();


        newContact = null;
        using(MemoryStream stream = new MemoryStream())
        {
            //Save the person to a stream
            person.WriteTo(stream);
            bytes = stream.ToArray();


            //save this to a file (by me)
            ByteArrayToFile("personStreamFromC#", bytes);
[...]

我将创建的文件“personStreamFromC#”复制到我的java解决方案中,并尝试使用以下java代码读取它:

 AddressBook.Builder addressBook = AddressBook.newBuilder();

// Read the existing address book.
try {
    FileInputStream input = new FileInputStream(args[0]);
    byte[] data = IOUtils.toByteArray(input);
    addressBook.mergeFrom(data);
  // Read the existing address book.
  AddressBook addressBookToReadFrom =
          AddressBook.parseFrom(new FileInputStream(args[0]));
  Print(addressBookToReadFrom);
}

但我收到以下消息:

  

线程“main”中的异常com.google.protobuf.InvalidProtocolBufferException:协议消息   标签有无效的电线类型。在   com.google.protobuf.InvalidProtocolBufferException.invalidWireType(InvalidProtocolBufferException.java:78)     在   com.google.protobuf.UnknownFieldSet $ Builder.mergeFieldFrom(UnknownFieldSet.java:498)     在   com.google.protobuf.GeneratedMessage $ Builder.parseUnknownField(GeneratedMessage.java:438)     在   com.example.tutorial.AddressBookProtos $消费$ Builder.mergeFrom(AddressBookProtos.java:1034)     在   com.example.tutorial.AddressBookProtos $消费$ Builder.mergeFrom(AddressBookProtos.java:1)     在   com.google.protobuf.CodedInputStream.readMessage(CodedInputStream.java:275)     在   com.example.tutorial.AddressBookProtos $通讯录$ Builder.mergeFrom(AddressBookProtos.java:1715)     在   com.example.tutorial.AddressBookProtos $通讯录$ Builder.mergeFrom(AddressBookProtos.java:1)     在   com.google.protobuf.AbstractMessage $ Builder.mergeFrom(AbstractMessage.java:300)     在   com.google.protobuf.AbstractMessage $ Builder.mergeFrom(AbstractMessage.java:238)     在   com.google.protobuf.AbstractMessageLite $ Builder.mergeFrom(AbstractMessageLite.java:162)     在   com.google.protobuf.AbstractMessage $ Builder.mergeFrom(AbstractMessage.java:716)     在   com.google.protobuf.AbstractMessage $ Builder.mergeFrom(AbstractMessage.java:238)     在   com.google.protobuf.AbstractMessageLite $ Builder.mergeFrom(AbstractMessageLite.java:153)     在   com.google.protobuf.AbstractMessage $ Builder.mergeFrom(AbstractMessage.java:709)     在AddPerson.main(test.java:104)

.proto文件下方:     包教程;     消息人{      必填字符串名称= 1;      required int32 id = 2; //此人的唯一身份证号码。      可选字符串email = 3;

 enum PhoneType {
   MOBILE = 0;
   HOME = 1;
   WORK = 2;
 }

 message PhoneNumber {
   required string number = 1;
  optional PhoneType type = 2 [default = HOME];
 }

 repeated PhoneNumber phone = 4;
 }

message AddressBook {
  repeated Person person = 1;
  }

任何想法??

2 个答案:

答案 0 :(得分:2)

您将Person对象写入 C#中的文件,但随后在 Java 中阅读AddressBook,我认为这不正确。请在Java代码中尝试以下内容:

Person.parseFrom(new FileInputStream(args[0]));

答案 1 :(得分:1)

导致无效线路类型错误(尤其是使用文件时)的一个常见错误是:覆盖现有文件而不截断它。我们无法看到您的ByteArrayToFile,但坦率地File.WriteAllBytes可能是一个更容易的选择。问题是,如果新数据小于原始内容,则任何剩余的额外字节基本上都是垃圾

我的建议:

  • 检查您是否可以在c#中反序列化它;如果你不能,错误肯定在文件处理中
  • 如果它在c#中工作,请检查如何将文件获取到java代码:你是在任何地方复制它吗?
  • 并检查您是否在所有阶段使用二进制(非文本)处理