ProtocolBuffers学习笔记
1. 简介
Protocol Buffers是google发明的一种数据交换格式,独立于语言,独立于平台。与其他的数据交换格式有所不同,Protocol Buffers是一种二进制的格式,因此在网络传输的时候效率更高,相对于json它的文件体积更小,相对于xml,它的解析速度更快。
作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于网络传输、配置文件、数据存储等领域。
2. 在java中的使用
2.1 新建test.proto文件
2.2 编译protot文件
下载编译器:
一般在每个发布版本的protoc-{版本号}-{平台}.zip压缩包里面包含对应的编译器。由于LZ用的是win系统,故下载了protoc-3.6.1-win32.zip
,解压之后在bin目录下会看到一个proto.exe
文件。在proto.exe
所在的目录下面就可以使用protoc
命令进行编译了。
实例:
编译成功后会在当前目录下生成对用的java文件:
2.3 在项目中使用编译好的java文件
protobuf的构造和获取如下:
新建一个java工程,目录结构如下:
导入protobuf-java-3.5.1.jar
(LZ使用的是此版本,读者请自行下载适用版本)。此包可以对ProtocolBuffer消息进行序列化和反序列化。
编写实例代码:
1)Constants.java
2)Server.java
3)Client.java
2.4 测试
先运行server。
再运行client。
server端已经接收到消息。
至此java中使用ProtocolBuffer的实例就完成了。
3. protobuf数据格式
protobuf消息定义的格式为:
3.1 限定修饰符
限定修饰符包含 required\optional\repeated。
限定符
含义
required
表示是一个必须字段,必须相对于发送方,在发送消息之前必须设置该字段的值,对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃。
optional
表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。因为optional字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为optional字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡。
repeated
表示该字段可以包含0~N个元素。其特性和optional一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值。 编译后的java文件对应类型为List。
3.2 数据类型
.proto类型
Java 类型
C++类型
备注
double
double
double
float
float
float
int32
int
int32
使用可变长编码方式。编码负数时不够高效——如果你的字段可能含有负数,那么请使用sint32。
int64
long
int64
使用可变长编码方式。编码负数时不够高效——如果你的字段可能含有负数,那么请使用sint64。
uint32
int[1]
uint32
无符号类型
uint64
long[1]
uint64
无符号类型
sint32
int
int32
使用可变长编码方式。有符号的整型值。编码时比通常的int32高效。
sint64
long
int64
使用可变长编码方式。有符号的整型值。编码时比通常的int64高效。
fixed32
int[1]
uint32
总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。
fixed64
long[1]
uint64
总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。
sfixed32
int
int32
总是4个字节。
sfixed64
long
int64
总是8个字节。
bool
boolean
bool
string
String
string
一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。
bytes
ByteString
string
可能包含任意顺序的字节数据。
3.3 字段名称
protobuf建议字段的命名采用以下划线分割的驼峰式。例如 first_name 而不是firstName。
3.4 字段编码值
有了该值,通信双方才能互相识别对方的字段。当然相同的编码值,其限定修饰符和数据类型必须相同。
编码值的取值范围为 1~2^32(4294967296)。
其中 1~15的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低。
protobuf 建议把经常要传递的值把其字段编码设置为1-15之间的值。消息中的字段的编码值无需连续,只要是合法的,并且不能在同一个消息中有字段包含相同的编码值。
3.5 默认值
当在传递数据时,对于required数据类型,如果用户没有设置值,则使用默认值传递到对端。当接受数据是,对于optional字段,如果没有接收到optional字段,则设置为默认值。
参考:
官方文档 https://developers.google.com/protocol-buffers/docs/javatutorial
Java中使用Protocol Buffer https://blog.csdn.net/yubo_725/article/details/52219489
Last updated