proto buffers是google的开源项目,提供结构化数据序列化的方法,一种轻便高效的数据格式,平台无关、语言无关、可扩、解析速度快,用于通讯协议和数据存储等领域。
通过在.proto文件中定义protocol buffer message类型,来结构化想要序列化的的信息。每一个 protocol buffer message 是一个信息的小逻辑记录,包含了一系列name-value 对。
1、proto2语法
一个.proto文件可以包含若干个message,每个message包含若干个字段,每一个字段包括字段,每一个字段包括字段规则、类型、名称以及编号
- 规则:字段规则有三种情况,required、optional、repeated(proto3删除了required,并且默认optional)
- orequired: 格式良好的 message 必须包含该字段一次
- optional: 格式良好的 message 可以包含该字段零次或一次
- repeated: 该字段可以在格式良好的消息中重复任意多次(包括零)。其中重复值的顺序会被保留(即数组)
- 类型:可以是标量类型(整形、实型、字符串等),还可以是复合类型,即枚举和其他message类型
- 编号:message 定义中的每个字段都有唯一编号,这些数字以 message 二进制格式标识字段
message SearchRequest {
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3;
}
2、.proto生成内容
.proto 编译时,编译器将会生成所需语言的代码,这些代码可以操作文件中描述的 message 类型,包括获取和设置字段值、将 message 序列化为输出流、以及从输入流中解析出 message。
- 对于 C++,编译器从每个 .proto 生成一个 .h 和 .cc 文件,其中包含文件中描述的每种 message 类型对应的类。
- 对于 Java,编译器为每个 message 类型生成一个 .java 文件(类),以及用于创建 message 类实例的特殊 Builder 类。
- Python 有点不同 - Python 编译器生成一个模块,其中包含 .proto 中每种 message 类型的静态描述符,然后与元类一起使用以创建必要的 Python 数据访问类。
- 对于 Go,编译器会生成一个 .pb.go 文件,其中包含对应每种 message 类型的类型。