我试图理解这里的协议缓冲区是示例,我无法理解的是在后续消息中如何使用字节。我不知道这个号码是多少
1 2 3
用于。
message Point {
required int32 x = 1;
required int32 y = 2;
optional string label = 3;
}
message Line {
required Point start = 1;
required Point end = 2;
optional string label = 3;
}
message Polyline {
repeated Point point = 1;
optional string label = 2;
}
我在google protobuf中读到以下段落,但无法理解这里说的是什么,任何人都可以帮助我理解字节用于存储信息的方式。
每个元素上的“= 1”,“= 2”标记标识字段在二进制编码中使用的唯一“标记”。标签号1-15比较高的数字需要少一个字节进行编码,因此作为优化,您可以决定将这些标签用于常用或重复的元素,将标签16和更高版本留给不太常用的可选元素。
答案 0 :(得分:3)
protobuf消息的一般形式是它是一对形式的对序列:
对于你的问题,我们可以在很大程度上忘记有效载荷 - 这不是与1/2/3和< = 16限制相关的位 - 所有这些都在字段标题中。字段标题是“varint”编码的整数; “varint”使用最高有效位作为可选的连续位,因此小值(< = 127,假设无符号而不是之字形)需要一个字节进行编码 - 较大的值需要多个字节。或者换句话说,在需要设置延续位之前,需要使用7个有用的位,至少需要2个字节。
然而!字段标题本身由两部分组成:
有线类型是前3位,表示有效载荷的基本格式 - “长度分隔”,“64位”,“32位”,“varint”,“start-group”, “末端基团”。这意味着在我们拥有的7个有用位中,只剩下4个; 4位足以编码数字< = 16。这是为最常见元素建议字段数< = 16(作为优化)的原因。
在你的问题中,1/2/3是字段编号;在编码时,它被左移3,并由有效载荷的线型组成;然后这个组合值是varint编码的。
答案 1 :(得分:1)
Protobuf将消息像id(他们称之为标签的= 1,= 2)的地图一样存储到实际值。这比传输数据更像是具有固定偏移的结构更容易扩展它。因此,例如,消息Point
在高级别上看起来像这样:
1 -> 100,
2 -> 500
然后将其解释为x=100
,y=500
和label=not set
。在较低级别,protobuf以高度紧凑的格式序列化此标记值映射,其中除了其他外,还存储具有可变长度编码的整数。您引用的段落只是在标签的情况下突出显示了这一点,如果它们是<标签,则可以更紧凑地存储。例如,16,但同样适用于protobuf定义中的整数值。