我正在阅读 Google Protocol Buffers
。我想知道我是否可以序列化 C++ 对象
并将其通过网络发送到 Java 服务器,然后在 java
中反序列化
并检查字段。
我想将任何语言的对象发送到 Java 服务器。并在那里反序列化。
假设以下是我的.proto
文件
message Person {
required int32 id = 1;
required string name = 2;
optional string email = 3;
}
我对此运行了 protoc
并创建了一个 C++
对象。
基本上现在我想将序列化流发送到 java
服务器。
在 java 端,我可以反序列化
流,这样我就可以发现流中有 3
字段及其各自的 name,type,和值(value)
最佳答案
Here on java side can I deserialized the stream , so that I can find out there are 3 fields in the stream and its respective
name
,type
, andvalue
您需要提前了解架构。首先,protobuf 不传输名称;它用作标识符的所有内容是每个字段的数字键(在您的示例中为 1
、2
和 3
)。其次,它没有明确指定类型; protobuf 中只有很少的线类型(varint、32 位、64 位、长度前缀、组);实际的数据 类型映射到那些类型,但您不能在没有架构的情况下明确解码数据
- varint 是“某种形式的整数”,但可以是有符号的、无符号的或“之字形”(允许对小负数进行廉价编码),并且可以用于表示任何宽度的数据(64 位, 32 位等)
- 32 位可以是整数,但可以是有符号或无符号 - 或者它可以是 32 位 float
- 64 位可以是整数,但可以是有符号或无符号 - 或者它可以是 64 位 float
- length-prefix 可以是 UTF-8 字符串、序列或原始字节(没有任何特定含义)、一些原始类型(整数、 float )的
repeated
值的“打包”集等),或者可以是 protobuf 格式的结构化子消息 - 团体 - 欢呼!这始终是明确的!这只能说明一件事;但谷歌在很大程度上不赞成使用这一点 :(
从根本上说:您需要架构。编码数据不包含您想要的内容。它这样做是为了避免不必要的空间——如果协议(protocol)假定编码器和解码器都知道消息的含义,那么需要发送的信息就会少很多。
但是请注意, 中包含的信息足以安全地往返消息,即使存在不需要的字段也是如此;如果您只需要对其进行重新编码以将其传递/传回,则无需知道名称或类型。
您可以做的是使用解析器 API 扫描数据以显示存在三个字段,字段 1 是 varint,字段 2 是长度前缀,字段 3 是长度-前缀。您可以对超出此范围的数据进行有根据的猜测(例如,您可以查看 UTF-8 解码是否产生了大致类似于文本的内容,并验证 UTF-8 编码是否返回给您原始字节;如果是,则可能它是一个字符串)
关于java - Google ProtoBuf 序列化/反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17081857/