简介
Protobuf全称是Google Protocol Buffer,是一种高效轻便的结构化数据存储方式,可用于(数据)通信协议、数据存储等。
也可以理解为结构化数据的序列化方法,可简单类比为XML(这里主要是指在数据通信和数据存储这些应用场景中序列化方面的类比,但个人认为XML作为一种扩展标记语言和Protobuf还是有着本质区别的),其具有以下特点:
- 语言无关,平台无关
Protobuf支持Java, C++, Python等多种语言,支持多个平台。 - 高效
比XML更小(3~10倍),更快(20 ~ 100倍),更为简单。 - 扩展性,兼容性好
你可以更新数据结构,而不影响和破坏原有的旧程序。
这里稍微解释一下序列化:
序列化将数据结构或对象转换成能够被存储和传输(例如网络传输)的格式,同时应当要保证这个序列化结果在之后(可能是另一个计算环境中)能够被重建回原来的数据结构或对象。
Protobuf 使用
- 创建.proto文件,定义数据结构
例如:
//例:在xxx.proto文件中定义Example1 message
message Example1{
optional string stringVal =1;
optional bytes bytesVal =2;
message EmbeddedMessage{
int32 int32Val = 1;
string stringVal = 2;
}
optional EmbededMessage embeddedExample = 3;
repeated int32 repeatedInt32Val = 4;
repeated string repeatedStringVal = 5;
}
我们在上例中定义了一个名为 Example1 的 消息,语法很简单,message 关键字后跟上消息名称:
message xxx{
}
之后我们在其中定义了message具有的字段,形式为:
message xxx {
// 字段规则:required -> 字段只能也必须出现 1 次
// 字段规则:optional -> 字段可出现 0 次或多次
// 字段规则:repeated -> 字段可出现任意多次(包括 0)
// 类型:int32、int64、sint32、sint64、string、32-bit ....
// 字段编号:0 ~ 536870911(除去 19000 到 19999 之间的数字)
字段规则 类型 名称 = 字段编号;
}
在上例中,我们定义了:
- 类型string,名为stringVal的optional可选字段,字段编号为1,此字段可出现0次或1次
- 类型bytes,名为bytesVal的optional可选字段,字段编号为2,此字段可出现0次或1次
- 类型 EmbeddedMessage(自定义的内嵌 message 类型),名为 embeddedExample1 的 optional 可选字段,字段编号为 3,此字段可出现 0 或 1 次
- 类型 int32,名为 repeatedInt32Val 的 repeated 可重复字段,字段编号为 4,此字段可出现 任意多次(包括 0)
- 类型 string,名为 repeatedStringVal 的 repeated 可重复字段,字段编号为 5,此字段可出现 任意多次(包括 0)
关于proto2定义message消息的更多语法细节,例如具体支持哪些类型,字段编号分配,import导入定义,请参考文章最后的Reference。
- protoc编译.proto文件生成读写接口
我们在.proto文件中定义了数据结构,这些数据结构是面向开发者和业务程序的,并不面向存储和传输。
当需要把这些数据进行存储或传输时,就需要将这些结构数据进行序列化、反序列化以及读写。那么如何实现呢?不用担心,ProtoBuf 将会为我们提供相应的接口代码。如何提供?答案就是通过 protoc 这个编译器。
可通过如下命令生成相应的接口代码:
// $SRC_DIR: .proto 所在的源目录
// --cpp_out: 生成 c++ 代码
// $DST_DIR: 生成代码的目标目录
// xxx.proto: 要针对哪个 proto 文件生成接口代码
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/xxx.proto
最终生成的代码将提供类似如下的接口:
Reference:
https://www.jianshu.com/p/a24c88c0526a