Protobuf簡單編寫與使用
阿新 • • 發佈:2021-01-07
Protobuf簡單介紹
首先Protobuf是google公司提出的一種序列化方法,因為其在網路傳輸中優點較多,同時使用簡單方便維護,因此現如今Protobuf以及逐漸取代Json來傳輸資料。
Protobuf與Json的對比
- 建立一個.proto檔案,在該檔案中定義了兩個訊息結構(student,teacher),
- 訊息結構在C++中對應的類分別為:student、teacher
如果我們使用Protobuf進行傳輸時,只需要對類進行賦值即可。
//name、age、gender分別為student類與teacher類的屬性
student類:
name:'張三'
age:20
gender:'男'
teacher類:
name:'張老師'
age:35
gender:'男'
如果我們使用Json進行資料傳輸時:
{"student":{"name":"張三","age":"20","gender":"男"},"teacher":{"name":"張老師","age":"35","gender":"男"})
Protobuf的語法
- 首先是定義語法格式,必須為第一行,表示後面的語法使用的是proto3語法,如果未寫,則預設採用proto2語法。
syntax = "proto3"
- 匯入其他proto檔案
import other.proto
- 申明作用域,方式產生衝突,類似C++中的namespace
package “xxx”
- 定義訊息格式
message Student{
required string name = 1;
required int32 age;
required string gender;
}
- required:修飾的欄位必須要設定
- optional:修飾的欄位可以有0個值或者1個值
- repeated:修飾的欄位可以重複任意多次
- 在使用期間,除非某個欄位一定需要被設定,否則使用optional或者repeated代替
- message類似於C++中的class
//建立PersonMsg.proto檔案
syntax = "proto3";//使用proto3語法格式
package PersonMsg;
message Person
{
required string name = 1;
required int32 age = 2;
required string gender = 3;
optional string email = 4;
enum Profession //職業
{
Strudent = 1;
Teacher = 2;
Worker = 3;
}
enum PhoneType //電話卡型別
{
MOBILE = 0; //移動
Link = 1; //聯通
}
message PhoneNumber{
requried string number = 1;
optional PhonType P_type = 2 [default = Link]; //電話卡預設型別為聯通
}
repeated PhoneNumber number = 5; //可以重複多次
}
message PersonMessage
{
repeated Person personInfo = 1;
}
編譯上述proto檔案,會生成PersonMsg.pb.h與PersonMsg.pb.cc兩個檔案
- .h檔案中儲存的是訊息類
- .cc檔案中儲存的是對訊息的一些操作,set,clear,has等操作
- Protobuf序列與反序列
#include<iostream>
#include"PersonMsg.pb.h"
using namespace std;
char buf[1024];
int main()
{
PersonMsg::PersonMessage person;
PersonMsg::Person* p = person.add_personInfo();
p->set_name("張三");
p->set_age(20);
p->set_gender("男");
if(!p->has_email())//如果獲取不到email,表示沒有email則對其進行初始化
{
p->set_email("[email protected]");
}
PersonMsg::Person::PhoneNumber* phonenum = person.add_number();
phonenum->set_number("xxxxx");
phonenum->set_P_type("PersonMsg::Person::Link");//設定電話
int size = person.ByteSize();
person.SerializeToArray(buf,size); //序列化
PersonMsg::PersonMessage person2;
person2.ParseFromArray(buf,size); //發序列化
return 0;
}