一、Protobuf是什么鬼?
Protobuf是Google基于C++ 进行的实现的一套数据序列化/反序列化库,开发人员可以根据 ProtoBuf 的语言规范生成多种编程语言(C++、Python、Java 等)的接口代码。使用ProtoBuf的文件在存储效率上和处理性能上都元高于XML,也具有更好的跨平台性,使用灵活。
二、Protobuf要怎么用?
Step1、根据需求写proto文件
proto文件即消息协议原型定义文件,在该文件中我们可以通过使用描述性语言,来定义程序中需要用到数据格式。首先Google给了一个电话簿的proto例子。
message Person {
requiredstring name = 1;
requiredint32 id = 2;
optionalstring email = 3;
messagePhoneNumber {
requiredstring number = 1;
optionalPhoneType type = 2 [default = HOME];
}
repeatedPhoneNumber phone = 4;
}
message AddressBook {
repeatedPerson person = 1;
}
一个Message是一个包含一组类型字段的集合。包括bool,int32,float,double和string或者自己定义的结构来定义一个Message。每一个类型字段前面必须要有一个修饰符包括:required、optional、repeated。
1)required字段的初值是必须要提供的,否则该字段会被认为“未初始化的”,在序列化和反序列化的时候会报错!所以,对于修饰符为required的字段,务必进行初始化赋值。
2)对于optional的字段而言,如果未进行初始化,那么会有默认值赋值该字段,如上述proto定义中的email 和PhoneType字段类型。
3)对于repeated的字段而言,该字段可以重复多个,上述的AddressBook例子便有个很好的该修饰符的应用场景,即每个人可能有多个电话号码。而在proto定义文件中可以使用repeated来修饰的字段类型,类似于一个数组,他可以包含多个数值。
其中字段标签标示了字段在二进制流中存放的位置,这个是必须的,而且序列化与反序列化的时候相同的字段的Tag值必须对应,否则反序列化会出现意想不到的问题。
Step2、编译proto文件,生成特定语言数据的数据定义代码
安装proto编译器方法,Windows版本:
https://github.com/protocolbuffers/protobuf/releases/tag/v3.7.1选择protoc-3.7.1-win32.zip 下载解压,将/bin/protoc.exe路径添加到环境变量中。运行编译器,指定源目录(你的应用程序源码目录——如果你不提供这个目录,默认就是当前目录),目标目录(你的应用程序编译后生成的代码的目录;通常用$SRC_DIR),还有你.proto文件的目录路径。在这种情况下,你可以
protoc -I=$SRC_DIR --cpp_out=$DST_DIR$SRC_DIR/addressbook.proto
如果你想生成Python的类,所以你要用--python_out选项——也有类似的选项支持其它语言,例如:
protoc -I=./ --python_out=./ ./addressbook.proto
Step3、将生成的.h、.c文件都引用到项目文件中
生成的C++的protocol buffer代码每个字段会生成一个has函数(has_value)、clear清除函数(clear_value)、set函数(set_value)、get函数(number和mutable_value)。这儿解释下get函数中的两个函数的区别,对于原型为const std::string&number() const的get函数而言,返回的是常量字段,不能对其值进行修改。但是在有一些情况下,对字段进行修改是必要的,所以提供了一个mutable版的get函数,通过获取字段变量的指针,从而达到改变其值的目的。
对于单一的成员变量设置值,可以使用对应的set_value函数;
对于repeated类型变量,可是使用对应的add_value()函数增加变量值;
对于union等不确定的类型变量,可以使用mutable_value()通过返回的指针设置变量值。
序列化反序列化:通过每个protocolbuffer类都有读message或写message的方法给你选择通过用protocol buffer binary format。包括:
SerializeToString(buff,length):序列化这个message和以字符串的方式返回。这是二进行字节,可以使用str类型作为一个方便的容器,类似的还有SerializeToArray()。
ParseFromString(buff,length):从给出的字符串中解析一条message。类似的还有ParseFromArray()
这里有只是一些使用解析和序列化的选项。此外,也会以看 Message API reference,查看完整的列表。
注意使用之前要引入Google的protobuf库,就可以正式使用pb协议编码解码数据
参考文档:
https://juejin.im/post/5bb597c2e51d450e6e03e42d
https://blog.csdn.net/losophy/article/details/17006573
https://developers.google.com/protocol-buffers/docs/downloads
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。