protobuf简介

本文介绍了Google的Protocol Buffers(简称PB),一种高效且跨平台的数据交换格式。PB支持多种编程语言,通过变长编码规则减少数据大小,适用于分布式应用间的数据通信。文章详细解析了Base-128变长编码和ZigZag编码方式,并说明了消息格式及字段编码类型的细节。

protobuf简介

protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

protobuf之所以小且快,就是因为使用变长的编码规则,只保存有用的信息,节省了大量空间。
1. Base-128变长编码
  - 每个字节使用低7位表示数字,除了最后一个字节,其他字节的最高位都设置为1;
  - 采用Little-Endian字节序。

 

-数字1:
0000 0001

-数字300:
1010 1100 0000 0010
000 0010 010 1100
-> 000 0010 010 1100
-> 100101100
-> 256 + 32 + 8 + 4 = 300

2. ZigZag编码

  Base-128变长编码会去掉整数前面那些没用的0,只保留低位的有效位,然而负数的补码表示有很多的1,所以protobuf先用ZigZag编码将所有的数值映射为无符号数,然后使用Base-128编码,ZigZag的编码规则如下:

1 (n << 1) ^ (n >> 31) or (n << 1) ^ (n >> 63)

负数右移后高位全变成1,再与左移一位后的值进行异或,就把高位那些无用的1全部变成0了,巧妙!

3. 消息格式

  每一个Protocol Buffers的Message包含一系列的字段(key/value),每个字段由字段头(key)和字段体(value)组成,字段头由一个变长32位整数表示,字段体由具体的数据结构和数据类型决定。 
字段头格式:

1 (field_number << 3) | wire_type
2 -field_number:字段序号
3 -wire_type:字段编码类型

4. 字段编码类型

TypeMeaningUsed For
0Varintint32, int64, uint32, uint64, sint32, sint64, bool, enum
164-bitfixed64, sfixed64, double
2Length-delimitedstring, bytes, embedded messages(嵌套message), packed repeated fields
3Start groupgroups (废弃) 
4End groupgroups (废弃)
532-bitfixed32, sfixed32, float

 

 

 

 

 

 

1. 编码风格 
  - 花括号的使用(参考上面的proto文件)
  - 数据类型使用驼峰命名法:AddressBook, PhoneType
  - 字段名小写并使用下划线连接:person_info, email_addr
  - 枚举量使用大写并用下划线连接:FIRST_VALUE, SECOND_VALUE

2. 适用场景

  "Protocol Buffers are not designed to handle large messages."。protobuf对于1M以下的message有很高的效率,但是当message是大于1M的大块数据时,protobuf的表现不是很好,请合理使用。

标量类型列表

proto类型C++类型备注
doubledouble 
floatfloat 
int32int32使用可变长编码,编码负数时不够高效——如果字段可能含有负数,请使用sint32
int64int64使用可变长编码,编码负数时不够高效——如果字段可能含有负数,请使用sint64
uint32uint32使用可变长编码
uint64uint64使用可变长编码
sint32int32使用可变长编码,有符号的整型值,编码时比通常的int32高效
sint64int64使用可变长编码,有符号的整型值,编码时比通常的int64高效
fixed32uint32总是4个字节,如果数值总是比总是比228大的话,这个类型会比uint32高效
fixed64uint64总是8个字节,如果数值总是比总是比256大的话,这个类型会比uint64高效
sfixed32int32总是4个字节
sfixed64int64总是8个字节
boolbool 
stringstring一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本
bytesstring可能包含任意顺序的字节数据

 

转载于:https://www.cnblogs.com/hnxxcxg/p/9405192.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值