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.缺乏自描述