Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Google协议缓冲区:找出字节[]中编码的消息_Java_Protocol Buffers - Fatal编程技术网

Java Google协议缓冲区:找出字节[]中编码的消息

Java Google协议缓冲区:找出字节[]中编码的消息,java,protocol-buffers,Java,Protocol Buffers,有没有办法找出字节[]中编码的消息类型?我是说,有没有可能发展出这样的东西: byte [] buf; if (typeOfMessage(buf) == "AProto") { AProto.parseFrom(buf); } else if (typeOfMessage(buf) == "BProto") { BProto.parseFrom(buf); } ... 不,不是。几个不同的消息可能都具有相同的字节[]表示形式。消息不会携带任何类型的信息。wire格式为每个标记值指

有没有办法找出字节[]中编码的消息类型?我是说,有没有可能发展出这样的东西:

byte [] buf;

if (typeOfMessage(buf) == "AProto") {
  AProto.parseFrom(buf);
} else if (typeOfMessage(buf) == "BProto") {
  BProto.parseFrom(buf);
}

...

不,不是。几个不同的消息可能都具有相同的
字节[]
表示形式。消息不会携带任何类型的信息。wire格式为每个标记值指示不同编码中的值编码,但仅此而已

但是,如果您想要此功能,则可以相对轻松地将其包装到您自己的消息中:

message MessageWithType {
  required string type_name = 1;
  required bytes data = 2;
}
基本上,这只是用它的类型名称包装每个真正的消息。当然,这只有在你控制整个过程的情况下才有效。。。如果您无法更改数据,则无法添加该信息


正如Kenton所指出的,如果您使用的是Protobuf 2.6.0+,那么您可以使用其中一个
来声明一条带有每种类型字段的消息(根据ursa的回答)。

如果您使用的是Protobuf 2.6.0+。但有一个窍门:

message DTO {
    // NOTE! The only and only message have to set.
    optional AProto aPhoto = 1;
    optional BPhoto bPhoto = 2;
    ...
    optional RenderRequest renderRequest = 20;
}
它在信息中添加了一些技术信息,所以你们总是知道你们在用什么。 当发生不兼容的更改时,它还允许跟踪版本控制:

message DTO {
    ...
    //optional BPhoto bPhoto = 2; // Compatibility broken in release 2014-10-09 by ursa
    optional BPhoto bPhoto = 21;
    ...
}

知道了。这意味着您无论如何都必须将META作为单独的数据传递(请注意,如果您有一小部分已知的可能消息类型,一个更干净的解决方案是创建一个包装消息,其中包含每种类型的可选字段。如果使用Protobuf 2.6.0,请使用新的
oneof
功能来指示只填充了一个字段。