java - 无法从文件读回 protobuf

标签 java android protocol-buffers

我正在将 protobuf 写入文件,然后再次读取,如下所示

protobuff block

Person personOne =
                  Person.newBuilder()
                    .setId(1234)
                    .setName("John Doe")
                    .setEmail("jdoe@example.com")
                    .addPhone(
                      Person.PhoneNumber.newBuilder()
                        .setNumber("555-4321")
                        .setType(Person.PhoneType.HOME))
                    .build();

写入文件,这里databyte[],参数是personOne.toByteArray()

        try {
             FileOutputStream output = new FileOutputStream(file);
             output.write(data);
             output.close();

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

从文件中读取,但在读取时出现错误

          try {

             FileInputStream input = new FileInputStream(file);
             byte [] buffer = new byte[input.read()];

             input.read(buffer);
             input.close();
             return buffer;

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

错误

    03-20 21:04:39.060: W/System.err(18074): com.google.protobuf.InvalidProtocolBufferException: Protocol message tag had invalid wire type.
    03-20 21:04:39.090: W/System.err(18074):    at com.google.protobuf.UnknownFieldSet$Builder.mergeFieldFrom(UnknownFieldSet.java:498)
    03-20 21:04:39.110: W/System.err(18074):    at com.google.protobuf.GeneratedMessage.parseUnknownField(GeneratedMessage.java:193)
    03-20 21:04:39.110: W/System.err(18074):    at com.example.protodemo.AddressBookProtos$Person.<init>(AddressBookProtos.java:124)
    03-20 21:04:39.110: W/System.err(18074):    at com.example.protodemo.AddressBookProtos$Person.<init>(AddressBookProtos.java:107)
    03-20 21:04:39.110: W/System.err(18074):    at com.example.protodemo.AddressBookProtos$Person$1.parsePartialFrom(AddressBookProtos.java:186)
    03-20 21:04:39.110: W/System.err(18074):    at com.example.protodemo.AddressBookProtos$Person$1.parsePartialFrom(AddressBookProtos.java:1)
    03-20 21:04:39.110: W/System.err(18074):    at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:141)
    03-20 21:04:39.110: W/System.err(18074):    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:176)
    03-20 21:04:39.110: W/System.err(18074):    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:188)
    03-20 21:04:39.110: W/System.err(18074):    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:193)
    03-20 21:04:39.110: W/System.err(18074):    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:49)
    03-20 21:04:39.120: W/System.err(18074):    at com.example.protodemo.AddressBookProtos$Person.parseFrom(AddressBookProtos.java:1088)
    03-20 21:04:39.120: W/System.err(18074):    at com.example.protodemo.MainActivity.onCreate(MainActivity.java:63)
    03-20 21:04:39.120: W/System.err(18074):    at android.app.Activity.performCreate(Activity.java:4470)
    03-20 21:04:39.120: W/System.err(18074):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1053)
    03-20 21:04:39.120: W/System.err(18074):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1934)
    03-20 21:04:39.120: W/System.err(18074):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
    03-20 21:04:39.120: W/System.err(18074):    at android.app.ActivityThread.access$600(ActivityThread.java:128)
    03-20 21:04:39.120: W/System.err(18074):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
    03-20 21:04:39.120: W/System.err(18074):    at android.os.Handler.dispatchMessage(Handler.java:99)
    03-20 21:04:39.120: W/System.err(18074):    at android.os.Looper.loop(Looper.java:137)
    03-20 21:04:39.120: W/System.err(18074):    at android.app.ActivityThread.main(ActivityThread.java:4517)
    03-20 21:04:39.120: W/System.err(18074):    at java.lang.reflect.Method.invokeNative(Native Method)
    03-20 21:04:39.120: W/System.err(18074):    at java.lang.reflect.Method.invoke(Method.java:511)
    03-20 21:04:39.130: W/System.err(18074):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
    03-20 21:04:39.130: W/System.err(18074):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
    03-20 21:04:39.130: W/System.err(18074):    at dalvik.system.NativeStart.main(Native Method)

更新 以前我将数据存储到 data.txt 文件中,但现在我已删除异常并收到新错误

03-20 21:25:58.920: W/System.err(18470): com.google.protobuf.InvalidProtocolBufferException: Protocol message tag had invalid wire type.
03-20 21:25:58.920: W/System.err(18470):    at com.google.protobuf.UnknownFieldSet$Builder.mergeFieldFrom(UnknownFieldSet.java:498)
03-20 21:25:58.920: W/System.err(18470):    at com.google.protobuf.GeneratedMessage.parseUnknownField(GeneratedMessage.java:193)
03-20 21:25:58.920: W/System.err(18470):    at com.example.protodemo.AddressBookProtos$Person.<init>(AddressBookProtos.java:124)
03-20 21:25:58.920: W/System.err(18470):    at com.example.protodemo.AddressBookProtos$Person.<init>(AddressBookProtos.java:107)
03-20 21:25:58.930: W/System.err(18470):    at com.example.protodemo.AddressBookProtos$Person$1.parsePartialFrom(AddressBookProtos.java:186)
03-20 21:25:58.930: W/System.err(18470):    at com.example.protodemo.AddressBookProtos$Person$1.parsePartialFrom(AddressBookProtos.java:1)
03-20 21:25:58.930: W/System.err(18470):    at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:141)
03-20 21:25:58.930: W/System.err(18470):    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:176)
03-20 21:25:58.930: W/System.err(18470):    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:188)
03-20 21:25:58.930: W/System.err(18470):    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:193)
03-20 21:25:58.930: W/System.err(18470):    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:49)
03-20 21:25:58.930: W/System.err(18470):    at com.example.protodemo.AddressBookProtos$Person.parseFrom(AddressBookProtos.java:1088)
03-20 21:25:58.930: W/System.err(18470):    at com.example.protodemo.MainActivity.onCreate(MainActivity.java:63)
03-20 21:25:58.930: W/System.err(18470):    at android.app.Activity.performCreate(Activity.java:4470)
03-20 21:25:58.930: W/System.err(18470):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1053)
03-20 21:25:58.930: W/System.err(18470):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1934)
03-20 21:25:58.930: W/System.err(18470):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
03-20 21:25:58.940: W/System.err(18470):    at android.app.ActivityThread.access$600(ActivityThread.java:128)
03-20 21:25:58.940: W/System.err(18470):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
03-20 21:25:58.940: W/System.err(18470):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-20 21:25:58.940: W/System.err(18470):    at android.os.Looper.loop(Looper.java:137)
03-20 21:25:58.940: W/System.err(18470):    at android.app.ActivityThread.main(ActivityThread.java:4517)
03-20 21:25:58.940: W/System.err(18470):    at java.lang.reflect.Method.invokeNative(Native Method)
03-20 21:25:58.940: W/System.err(18470):    at java.lang.reflect.Method.invoke(Method.java:511)
03-20 21:25:58.940: W/System.err(18470):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
03-20 21:25:58.940: W/System.err(18470):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
03-20 21:25:58.940: W/System.err(18470):    at dalvik.system.NativeStart.main(Native Method)

最佳答案

从您的代码中:

byte [] buffer = new byte[input.read()];

在这里,您似乎正在读取输入的第一个字节并将其用作缓冲区的大小。然而,当你写入文件时,你实际上并没有在第一个字节中写入大小;而是在第一个字节中写入大小。你只写了数据:

FileOutputStream output = new FileOutputStream(file);
output.write(data);
output.close();

无需将文件内容读取到 byte[],只需将输入流本身传递给 parseFrom,例如:

FileInputStream input = new FileInputStream(file);
Person person = Person.parseFrom(input);

如果必须读入字节数组,则根据文件的实际大小分配数组,例如使用File#length()。或者,在写入消息之前实际写入消息大小。 (不过,不要将其写为单个字节,因为如果消息大于 255 个字节,就会出现问题。)

关于java - 无法从文件读回 protobuf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22537891/

相关文章:

java - AcharEngine制作日期相关图表

java - 尝试在 Java 中更新 MySQL 数据库时数组索引越界异常

Android:线程间歇性暂停

java - 如何使用 long 和 int 数据类型更新进度条的进度(使用 0-100 整数)?

android - 使用 Android 设计支持库时出错 : attr backgroundTint not found

protocol-buffers - Protobuf 校验和 (crc)

java - 关于 Google Protocol Buffer 的查询

java - 如何与一个 Erlang 节点中的特定进程进行通信?

c++ - protobuf,如何在我不太了解的 protobuf 消息中遍历所有设置字段?(C++)

java - 基于注释参数创建切入点