协议缓冲区,序列化数据中包含什么?

时间:2018-12-06 16:53:34

标签: java protocol-buffers google-protocol-buffer protocol-buffers-3

我是协议缓冲区的新手,真的想了解更多有关它的信息,对不起菜鸟问题。

什么是序列化数据,仅值或键和值两者?我认为只有价值观,如果有人想反序列化,他/她必须有计划。

2 个答案:

答案 0 :(得分:3)

既是键又是值:

  

如您所知,协议缓冲区消息是一系列键值对。   邮件的二进制版本仅使用该字段的编号作为   键–每个字段的名称和声明的类型只能确定   在解码端通过引用消息类型的定义(即   .proto文件)。   https://developers.google.com/protocol-buffers/docs/encoding

例如,假设您有一个原始文件,如下所示:

$  cat my.proto 
message header {
  required uint32 u1 = 1;
  required uint32 u2 = 2;
  optional uint32 u3 = 3 [default=0];
  optional bool   b1 = 4 [default=true];
  optional string s1 = 5;
  optional uint32 u4 = 6;
  optional uint32 u5 = 7;
  optional string s2 = 9;
  optional string s3   = 10; 
  optional uint32 u6 = 8;
}

从内存中转储编码数据:

(gdb) x/10xb 0x7fd70db7e964
0x7fd70db7e964: 0x08    0xff    0xff    0x01    0x10    0x08    0x40    0xf7
0x7fd70db7e96c: 0xd4    0x38

解码:

$ echo 08ffff01100840f7d438 | xxd -r -p | protoc --decode_raw
1: 32767
2: 8
8: 928375

1,2,8是键

来自上方的原始文件:

1 => u1, 
2 => u2,
8 => u6

因此,它变成:

u1: 32767
u2: 8
u6: 928375

我使用了问题here中的数据:

答案 1 :(得分:1)

这在某种程度上取决于您使用二进制格式(通常是处理protobuf时的默认格式)还是使用json格式(是的,protobuf至少在某些库中-并非全部包含json选项)。 / p>

以二进制形式,数据由字段 numbers 和值组成;不是名称字段。例如,如果我们使用以下示例:

optional string name = 1; // remove the "optional" if using proto3 syntax

并分配值“ Nika”(并将其序列化),则二进制数据将包括1(以略微调整的形式)和UTF-8编码形式的Nika ,但包含“名称”。

您并不需要绝对需要对其进行解码,但是如果这样做的话,它将使很多变得更加容易,因为该规范的许多部分否则会产生歧义,对于多种数据类型或同一数据类型的多个含义使用相同的“导线类型”(即编码格式)(例如:您无法确定整数是否为没有模式(或很好的猜测)的带符号,无符号或“ zig zag编码”,基于此,您获得的实际值可能会有很大差异。

要查看您在没有模式的情况下可以从原始protobuf数据中获取什么,请尝试:https://protogen.marcgravell.com/decode