如何处理Java中未知的protobuf字段?

如何处理Java中未知的protobuf字段?,java,protocol-buffers,protobuf-java,Java,Protocol Buffers,Protobuf Java,我有一个Java应用程序,它从另一台计算机读取一些protobuf数据,然后修改一些值并将其写回。很可能用户可以使用过时的.proto文件读取数据,因此在这种情况下,可能会有一些字段无法理解。我最终希望在写回所做的更改时保留uknown数据;但是,我可以满足于只检测未知数据(以提示用户升级其应用程序)。我不清楚如何处理Java中的未知字段 如果有帮助的话,我正在使用2.proto版本的文件,因为我需要它与远程计算机上的nanopb兼容 这让我明白了一部分,但我的问题与JSON无关。首先,当你说未

我有一个Java应用程序,它从另一台计算机读取一些protobuf数据,然后修改一些值并将其写回。很可能用户可以使用过时的.proto文件读取数据,因此在这种情况下,可能会有一些字段无法理解。我最终希望在写回所做的更改时保留uknown数据;但是,我可以满足于只检测未知数据(以提示用户升级其应用程序)。我不清楚如何处理Java中的未知字段

如果有帮助的话,我正在使用2.proto版本的文件,因为我需要它与远程计算机上的nanopb兼容


这让我明白了一部分,但我的问题与JSON无关。

首先,当你说未知字段时,请注意。在protobuf中,根据定义可以有未知字段,但另一方面——我想这是您的情况——可以有当前proto文件中没有的字段

在这两种情况下,您都可以轻松访问这些值。假设您有一条名为foo的原始消息

您必须访问描述符并按名称从中获取字段,最后获取如下示例所示的值:

Builder builder = foo.toBuilder();
FieldDescriptor field = builder.getDescriptorForType().findFieldByName("whatever field");
Object obj = builder.getField(field);

// if your field is int32 cast to int
int value = (int) obj
如果您希望写入“未知”值,您可以采用另一种方法:

Builder builder = foo.toBuilder();
FieldDescriptor field = builder.getDescriptorForType().findFieldByName("whatever field");
builder.setField(field, 100); // 100 is an example int value
Foo foo = builder.build();
如果您确实想插入原始定义的未知字段,则必须执行以下操作:

 UnknownFieldSet.Field seqField = UnknownFieldSet.Field
            .newBuilder()
            .addFixed32(100) // 100 is an example int value
            .build();

 UnknownFieldSet unkFieldSet = UnknownFieldSet
            .newBuilder()
            .addField(99, seqField) // 99 is a proto index number chosen by me
            .build();

 Foo message = foo.toBuilder().setUnknownFields(unkFieldSet).build();
再次读取已定义的未知字段由以下步骤完成:

 foo.toBuilder().getUnknownFields()....

我希望这会有所帮助。

当用户使用过时的.proto文件打开数据时,您是否测试了该行为?在这种情况下,您是否可以捕获并响应一个简单的异常?如果您使用protoc生成java类,它包含unknownFields字段,它将填充标记号和值(因为新proto包含例如标记4,这在过时的proto文件中不可用)