protobuf介绍
protobuf是google开发的语言独立的结构化数据存储或RPC数据交换格式。它与语言无关,平台无关。
安装protobuf(c++),Ubuntu16.0.4下安装
sudo apt-get install autoconf automake libtool curl make g++ unzip
git clone [email protected]:google/protobuf.git
cd protobuf
./autogen.sh
./configure
make -j4
sudo make install
sudo ldconfig
定义protobuf数据格式
假设我们定义关于一个人的信息,有此人的名字,身份证号码,email信息(可选,不是必须的),电话:手机,家庭电话,工作电话。手机号码是字符串,默认为家庭电话。
proto文件描述如下
syntax = "proto2";
package tutorial;
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}
- syntax:表明使用的proto2还是proto3,两个版本并无完全兼容,proto3语法更加简洁支持更多语言:Java,C++,Python,Java Lite,Ruby,JavaScript,Objective-C,C#
- package:包的名字,主要是为了防止名称冲突。
- message:消息,类型域的集合,类型通常包含(bool,int32,float,double和string),上面的例子中消息Person包含了消息PhoneNumber,AddressBook消息包含Person消息
=1
,=2
标记是每个元素定义的独一无二的t使用二进制编码的tag域1-15要求编码小于1byte,大于14的比较少用。在repeated域中的每个元素要求重新编码tag数,因此重复域可用于优化。16-2047占据2bytes,最小的tag可以为1,最大可以为 ,不能使用19000-19999(他们作为保留的PB实现)- required(proto2):表示这个域的值必须提供否则消息将被当做没有初始化。序列一个没有初始化的消息将生成异常。解析一个没有初始化的消息将失败。除此外required域的行为和optional域类似。
- optional(proto2):一个也许指定也许没有指定的域。如果optional域没有设置值,默认值被使用。正如上面例子中的PhoneNumber的类型,对于数值默认值为0,字符串的默认值为空,bool的默认值为false。embedded消息默认值是消息的
默认实例
或者原型
,调用装饰器获取选项值如果没有明确设置将总是返回域的默认值。 - repeated(proto2,proto3):重复任何次数(包括0次)。重复值的顺序将被保留在protocol buffer。考虑重复域作为动态数组。proto3中默认使用
packed
编码 -
- sigular:可以有0个或者一个这样的域
- sigular:可以有0个或者一个这样的域
proto文件的注释风格和C++类似
/**/
或者//
编译Protobuf文件
SRC_DIR
:程序源代码所在的路径DST_DIR
: 生成目标的存储路径--python_out(cc_out)
:生成的指定的语言的的文件到DST_DIR中。- 运行命令
protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/addressbook.proto
将在DST_DIR
下产生对应的文件,包含序列化/解析整个结构的为/从原子bytes。