有没有办法在没有代码生成的情况下编写原型数据?

Gae*_* E. 8 java reflection protocol-buffers

我想知道是否可以使用google protobuf提供的反射API来序列化消息而无需代码生成?

协议缓冲区允许我们在解析过程后使用反射MessageMessage.Builder对象.但在我的情况下,我想知道我是否可以用字段/值填充这些对象,然后将它们写入文件.

Mai*_*aik 8

编码输出流

实现此目的的一种方法是了解消息的编码方式,并使用CodedOutputStream通过适当的方法写入消息字段write*()

例如写下以下消息:

message MyMessage {
    int foo = 1;
    string bar = 2;
}
Run Code Online (Sandbox Code Playgroud)

您将使用这段代码:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
CodedOutputStream out = CodedOutputStream.newInstance(baos);
out.writeInt32(1, 1);
out.writeString(2, "s");
out.flush();
byte[] rawProtocolBuffer = baos.toByteArray();
Run Code Online (Sandbox Code Playgroud)

动态消息

另一种方法是手动创建描述符,然后用于DynamicMessage设置相应的字段,但这比CodedOutputStream直接使用更加样板。

String messageName = "MyMessage";
FileDescriptorProto fileDescriptorProto = FileDescriptorProto
        .newBuilder()
        .addMessageType(DescriptorProto.newBuilder()
                .setName(messageName)
                .addField(FieldDescriptorProto.newBuilder()
                        .setName("foo")
                        .setNumber(1)
                        .setType(FieldDescriptorProto.Type.TYPE_INT32)
                        .build())
                .addField(FieldDescriptorProto.newBuilder()
                        .setName("bar")
                        .setNumber(2)
                        .setType(FieldDescriptorProto.Type.TYPE_STRING)
                        .build())
                .build())
        .build();

Descriptor messageDescriptor = FileDescriptor
        .buildFrom(fileDescriptorProto, new FileDescriptor[0])
        .findMessageTypeByName(messageName);

DynamicMessage message = DynamicMessage
        .newBuilder(messageDescriptor)
        .setField(messageDescriptor.findFieldByNumber(1), 1)
        .setField(messageDescriptor.findFieldByName("bar"), "s")
        .build();

byte[] rawProtocolBuffer = message.toByteArray();
Run Code Online (Sandbox Code Playgroud)