java - Google ProtoBuf 序列化/反序列化

标签 java c++ protocol-buffers

我正在阅读 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, and value

您需要提前了解架构。首先,protobuf 不传输名称;它用作标识符的所有内容是每个字段的数字键(在您的示例中为 123)。其次,它没有明确指定类型; 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/

相关文章:

java - 将输入解析为数组时出现 NumberFormatException : For input string: "",

java - 无法使用Java删除系统目录中的文件

java - "Etat HTTP 500"错误的原因是什么?怎么解决呢?

java.lang.UnsatisfiedLinkError : Native method not found 错误

c - void *array = *(void **) member + siz * (*p_n); 的目的是什么?

tcp - 使用 protobuf-net 反序列化 Protocol Buffer 时如何指定流长度?

java - 未正确添加客户总数

C++:用户定义类的动态数组

C++ 和 C 非成员多结构初始化

protocol-buffers - 如何将我自己的代码从 proto 文件添加到 JAVA 生成的类中?