protobuf介绍
谷歌开源的Protocol Buffer
,简称protobuf
,是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化,且不受平台和语言的限制。
简单来说,如果你需要存储数据,且这些数据为多个程序所共享,涉及数据的传输与接收问题,需要数据的序列化与反序列化,那么protobuf
就非常适合你了。它不但可以帮你完成数据的存储,数据传输时的序列化和反序列化,并且适用于不同编程语言下的数据传输,即一个C++程序作为发送端,接收端既可以是C++程序,也可以是java程序。
你可以用定义自己ProtoBuf的数据结构,用ProtoBuf编译器生成特定语言的源代码,(如C++,Java,Python等,目前ProtoBuf对主流的编程语言都提供了支持)方便的进行序列化和反序列化。
三种修饰符
- required : 不可以增加或删除的字段,必须初始化;
- optional : 可选字段,可删除,可以不初始化;
- repeated : 可重复字段, 对应到java文件里,生成的是List。
使用方法
- 定义结构
syntax="proto2";
message temp{
required string name = 1;
required int32 score = 2;
}
这个文件用来生成,存储数据的结构,相当于C++中的结构体。
我们可以用这个文件来生成你想要的程序:这里生成C++程序,包括头文件和源文件
~/third_part/bin/protoc temp.proto --cpp_out=.
//结构: protoc的路径 protobuf文件名 生成方式(这里c++)=生成文件路径
这样就会在你指定的路径下生成指定的相应的C++头文件和源文件,如:
temp.pb.h
和 temp.pb.cc
- 使用该结构,用该结构定义变量
#include "temp.pb.h"
temp tem_;
tem_.set_score(100);
tem_.set_name("aaaa");
包含头文件后就可以直接定义变量了,但是赋值得调用set_ + 变量名
这个函数来进行赋值
- 序列化和反序列化
string buf;
tem_.SerializeToString(&buf); //tem_序列化存储到 buf里
temp _get;
_get.ParseFromString(buf);//将buf的值反序列化到_grt
//此时_get和tem_里的值一样
- 使用成员
cout<<_get.name()<<endl;
cout<<_get.score()<<endl;
同样不能直接使用,要调用变量名()
这个函数来得到成员的值。
完整代码 (环境:Linux Centos7)
- temp.proto文件
syntax="proto2";
message temp{
required string name = 1;
required int32 score = 2;
}
- main.cc文件
#include <iostream>
#include "temp.pb.h"
using namespace std;
int main()
{
temp tem_;
tem_.set_score(100);
tem_.set_name("aaaa");
string buf;
tem_.SerializeToString(&buf);
cout<<buf<<endl;
temp _get;
_get.ParseFromString(buf);
cout<<_get.name()<<endl;
cout<<_get.score()<<endl;
return 0;
}
- Makefiel文件
PROTOC=~/third_part/bin/protoc
main:main.cc temp.pb.cc
g++ $^ -o $@ -I ~/third_part/include -L ~/third_part/lib -lprotobuf
temp.pb.cc:temp.proto
$(PROTOC) temp.proto --cpp_out=.
.PHONY:clear
clear:
rm temp.pb.cc temp.pb.h
运行结果
这是一简单的示例,仅仅在两个变量中完成了,数据的序列化和反序列化,实际上用于在网络中传输数据也是非常高效的。