一、概念
Google使用的混合语言数据标准,用于RPC系统和持续数据存储系统。
protobuf是一种轻便高效的一种结构化数据的存储格式,用于结构化数据序列化。适合做数据存储或者RPC数据交换格式。用于即时通信,数据存储等领域的语言无关,平台无关,可扩展的序列化结构数据格式。
核心包括:定义消息(消息的结构体,以message标识),定义接口(接口路径和参数,以service标识)
通过protobuf提供机制服务端和服务端之间只需要关注结构方法名(service)和参数(message)即可通信,降低了服务器端开发成本。
二、与json和xml的区别
protobuf比json,xml体积更小,解析速度更快。(因为protobuf序列化后是二进制的格式)
1)、数据格式
是google开发的一种数据序列化协议(与json,xml类似),可以序列化数据后进行网络通信或者结构化存储。
xml是扩展标记语言,传输和存储数据,有自我描述性。
json是一种轻量级的数据交换格式,易于理解和编写。
2)、序列化后数据大小
XML > JSON > prtobuf
3)、可读性
protobuf序列化后是二进制数据
JSON序列化后为易阅读的文本
XML易阅读的文本,可读性最好
4)、语言支持
protobuf提供了多种编程语言的API支持
JSON被所有语言支持
XML被几乎所有语言支持
5)、使用场景
protobuf用于网络通信和结构化数据存储
JSON主要用于Web前后端数据交互
XML各种信息系统中存储和交换数据
三、字段规则
singlar:可以有零个或者其中一个字段
repeated该字段可以重复任意次数。
reserved保留字段:通过完全删除某个字段或者对其进行注释来更新消息类型
message:定义消息类型-可以嵌套
oneof:同时包含多个类型的字段, 和上一层字段属于同一级别,不能重名,不能用repeated修饰,oneof内只能有一个字段被设置
map:将键值添加到定义中
enum:枚举类型,第一个元素必须设置为0。
message student{
string name = 1;
int age = 2;
oneof contaction{
string qq = 3;
string wechat = 4;
}
}
四、protobuf编译
protobuf -I=$SRC_DIR --cpp_c++_out=SRC_DIR/*.proto
#SRC_DIR: :.proto 文件所在目录
#--cpp_out : 生成c++代码
# ¥DST_DIR: 生成代码的目录
# *.proto : 对所有的.proto文件生成接口代码
g++ -o main main.cpp x.cc -lprotobuf
五、简单的代码实现
//.proto---可以生成.cc 和.h文件
syntax = "proto3";
package pro;
message student{
optional string name = 1;
optional int32 age = 2;
message course_soures{
optional string course =1;
repeated int32 scores = 2;
}
course_soures p = 3;
}
//.sh
#!/bin/bash
SCR_DIR=/home/dolphin/hua/text_json
DES_DIR=/home/dolphin/hua/text_json
protoc --proto_path=$SCR_DIR --cpp_out=$DES_DIR $SCR_DIR/*.proto
//.cpp文件
#include<iostream>
#include<string>
using namespace std;
#include"pro.pb.h"
#include<google/protobuf/message.h>
#include<google/protobuf/util/json_util.h>
int main(){
GOOGLE_PROTOBUF_VERSION;//作用:如果检测到版本不匹配时,程序将终止。
pro::student s;//创建一个student对象
s.set_name("huhua");
s.set_age(21);
//
//
/* //直接进行字段设置
//创建一个course_soures 对象
pro::student::course_soures * cs = new pro::student::course_soures();
cs->set_course("shuxue");
cs->add_scores(92);
cs->add_scores(90);
s.set_allocated_p(cs);
*/
/*//使用vector 赋值给 scores
vector<int> v = {1, 2, 3, 4};
pro::student::course_soures cs;
*cs.mutable_scores() =google::protobuf::RepeatedField<google::protobuf::int32> {v.begin(), v.end()};
*(s.mutable_p()) = cs;
*/
//scores赋值给变长数组vector
pro::student::course_soures * course = s.mutable_p();
course->set_course("huaxue");
vector<int32_t> v = {20, 99 ,67};
for(int x : v ){
course->add_scores(x);
}
pro::student::course_soures cs;
string json_str;
google::protobuf::util::Status st = google::protobuf::util::MessageToJsonString(s, &json_str);
cout << "json str :" << st.ToString() << endl;
cout <<json_str <<endl;
/*
string send_str;
if(s.SerializeToString(&send_str)){
cout << send_str.c_str() << endl;
}
pro::student s1;
if(s.ParseFromString(send_str)){
cout << s1.name() << endl;
cout << s1.age() << endl;
}
*/
//在程序结束的时候加上 google::protobuf::ShutdownProtobufLibrary(); 的函数调用。它主要做的工作是对protobuf 全局资源的清理工作。
exit(0);
}