优点:
a. 该数据接口编码出的数据占用内存空间小,约是json的30%~40%。 b. 传输效率高,耗费流量少,因为是字节码,编解码效率,也比json从字节码转换成对象流更快。 c. 传输过程的安全性也有所提高,因为是字节码,抓包器抓到的也只是字节二进制数据。 d. 支持多种语言的编译:c c++ java python c#等等。 e. 编写的proto数据结构文件,前后端都通用。 复制代码
缺点:
a. 因为是google的产品,通用性和xml和json比相对较差。 b. 如果传输的数据,数据结构比较复杂,编写proto的数据结构文件会复杂啰嗦,且教容易出错。 复制代码
protobuffer被用在很多领域:数据传输、游戏开发的数据通信、大数据领域的数据存储压缩、即时通讯IM(QQ、微信)
在protobuffer的IDL文件中(int32, int64, uint32, uint64, sint32, sint64, bool, enum)这些数据类型使用varint来编码
varint编码过程:在java中int需要4个字节,对于小于256的整型数字protobuf通过int32类型来表示,用varint编码只需要1个字节。 虽然大的数字需要更多的字节,但是统计表明大多数情况都是较小的数字,varint编码可以用更少的字节来表示数字,从而更好的压缩数据。
// 有300个学生 int32 studentNums = 300; 300的二进制:java中int为4个字节,32位 步骤一:0000 0000 0000 0000 0000 0001 0010 1100 // 原始数据300转换成二进制 010 1100 // 将字节串的末尾取出7位bit 1010 1100 // 因为前面一个字节还有数据,所以在当前7位bit的这个字节最高位补1 步骤二:0000 0000 0000 0000 0000 0001 0010 1100 00 0001 0 // 因为前面一个字节还有数据,再取出字节串的这7bit 000 0001 0 // 因为前面字节没有数据了,最高位补0 步骤三:把步骤一和步骤二提取生成的字节串拼接 因为采用了小端字节序,所以步骤一低位字节放在高位地址,步骤二高位字节放在地位地址 (步骤一) (步骤二) 1010 1100 ++ 000 0001 0 ===> 1010 1100 0000 0010 将原来int32表示的4字节值:300 经过varint编码==> 2字节的 压缩了数据 复制代码
varint解码:10101100 00000010(两个字节的字节数组) ===> 解码后为:300(4个字节的原始数据)
1010 1100 0000 0010 010 1100 000 0010 // 把每个字节的最高位去掉 ======== ======== || 将两个字节调换 || 000 0010 010 1100 // 把去掉高位后的两个字节调换 || // 编码时采用了小端字节序,而java正常采用的是大端字节序读取模式,所以解码时要调换字节 || // 高低位字节调换后,合并就是 300的二进制值了 100101100 => 1 00 1 0 1 1 0 0 256 + 32 + 8 + 4 = 300复制代码