1. 程式人生 > 其它 >Protobuf簡單編寫與使用

Protobuf簡單編寫與使用

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;
}
  1. required:修飾的欄位必須要設定
  2. optional:修飾的欄位可以有0個值或者1個值
  3. repeated:修飾的欄位可以重複任意多次
  4. 在使用期間,除非某個欄位一定需要被設定,否則使用optional或者repeated代替
  5. 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;
}