2

C#でストリームを作成し、Javaで読み込もうとしていますが、「プロトコルメッセージタグのワイヤタイプが無効です」というエラーが表示されます。私がJavaコードでそれを読んだとき、c#で作成されたオブジェクト。

詳細: 同等の.protoファイル(以下を参照)から始めて、対応する.javaファイルと.csファイルを作成しました(バージョン「protobuf-2.4.1」のprotoc for javaと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)at com.google.protobuf.UnknownFieldSet $ Builder.mergeFieldFrom(UnknownFieldSet.java:498)at com.google.protobuf.GeneratedMessage $ Builder.parseUnknownField(GeneratedMessage .java:438)at com.example.tutorial.AddressBookProtos $ Person $ Builder.mergeFrom(AddressBookProtos.java:1034)at com.example.tutorial.AddressBookProtos $ Person $ Builder.mergeFrom(AddressBookProtos.java:1)atcom。 google.protobuf.CodedInputStream.readMessage(CodedInputStream.java:275)at com.example.tutorial.AddressBookProtos $ AddressBook $ Builder.mergeFrom(AddressBookProtos.java:1715)atcom.example。

.protoファイルの下: パッケージチュートリアル; メッセージPerson{必須の文字列名=1; 必要なint32id= 2; //この人の一意のID番号。オプションの文字列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;
  }

何か案は ??

4

2 に答える 2

2

オブジェクトをC#Personでファイルに書き込みますが、Javaで読み取ると、これは正しくないと思います。Javaコードで次のことを試してください。AddressBook

Person.parseFrom(new FileInputStream(args[0]));
于 2012-12-24T12:43:02.107 に答える
1

無効なワイヤタイプのエラーを引き起こす可能性のある一般的な間違いの1つ、既存のファイルを切り捨てずに上書きすることです。ByteArrayToFileは表示されませんが、率直に言っFile.WriteAllBytesて、より簡単なオプションである可能性があります。問題は、新しいデータが元の内容よりも小さい場合、残りの余分なバイトは本質的にゴミであるということです。

私のアドバイス:

  • C#で逆シリアル化できるかどうかを確認してください。できない場合、エラーは確かにファイル処理にあります
  • それがc#で動作する場合は、ファイルをJavaコードにどのように取得しているかを確認してください。どこにでもコピーしていますか?
  • すべての段階でバイナリ(テキストではない)処理を使用していることを確認します
于 2012-12-24T10:36:37.527 に答える