Protobuf簡介

林堯彬發表於2020-04-04

1. 用途:

 把某種資料結構的資訊,以某種格式儲存起來。主要用於資料儲存、傳輸協議格式等場合。

2. 優點:

  a.效能好,效率高(時間和空間上比XML好,XML反序列化開銷大)

  b.程式碼生成機制

eg:

    假設訂單包括如下屬性:

--------------------------------

    時間:time(用整數表示)

    客戶id:userid(用整數表示)

    交易金額:price(用浮點數表示)

    交易的描述:desc(用字串表示)

--------------------------------

    如果使用protobuf實現,首先要寫一個proto檔案(不妨叫Order.proto),在該檔案中新增一個名為"Order"的message結構,用來描述通訊協議中的結構化資料。該檔案的內容大致如下:

 

--------------------------------

message Order

{

  required int32 time = 1;

  required int32 userid = 2;

  required float price = 3;

  optional string desc = 4;

}

--------------------------------

 

 

    然後,使用protobuf內建的編譯器編譯 該proto。由於本例子的模組是C++,你可以通過protobuf編譯器的命令列引數(看“這裡 ”),讓它生成C++語言的“訂單包裝類”。(一般來說,一個message結構會生成一個包裝類)

    然後你使用類似下面的程式碼來序列化/解析該訂單包裝類:

 

--------------------------------

// 傳送方

Order order;

order.set_time(XXXX);

order.set_userid(123);

order.set_price(100.0f);

order.set_desc("a test order");

string sOrder;

order.SerailzeToString(&sOrder);

// 然後呼叫某種socket的通訊庫把序列化之後的字串傳送出去

// ......

--------------------------------

// 接收方

string sOrder;

// 先通過網路通訊庫接收到資料,存放到某字串sOrder

// ......

Order order;

if(order.ParseFromString(sOrder))  // 解析該字串

{

  cout << "userid:" << order.userid() << endl

          << "desc:" << order.desc() << endl;

}

else

{

  cerr << "parse error!" << endl;

}

 

--------------------------------

 

    有了這種程式碼生成機制,開發人員就不用再編寫協議解析的程式碼。萬一將來需求發生變更,要求給訂單再增加一個“狀態”的屬性,那隻需要在Order.proto檔案中增加一行程式碼。對於傳送方(模組A),只要增加一行設定狀態的程式碼;對於接收方(模組B)只要增加一行讀取狀態的程式碼。

  c.支援“向後相容”和“向前相容”

     “向後相容”:當模組B升級之後,它能夠正確識別模組A發出的老版本的協議。如上例中,由於老版本沒有“狀態”這個屬性,在擴充協議時,可以考慮把“狀態”屬性設定成為非必填的,或者給“狀態”屬性設定一個預設值。

    “向前相容”:當模組A升級以後,模組B能夠 正常識別模組A發出的新版本的協議,這時新增加的“狀態”屬性會被忽略。

  d.支援多種程式語言(官方原始碼中包含了C++、Java、Python三種語言)

3. 缺點:

  a.應用不夠廣

  b.二進位制格式導致可讀性差

  c.缺乏自描述

轉載於:https://www.cnblogs.com/liuyucat/p/3433921.html