1. 用途:編程
把某種數據結構的信息,以某種格式保存起來。主要用於數據存儲、傳輸協議格式等場合。網絡
2. 優勢:數據結構
a.性能好,效率高(時間和空間上比XML好,XML反序列化開銷大)socket
b.代碼生成機制編程語言
eg:性能
假設訂單包括以下屬性:ui
--------------------------------spa
時間: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.缺少自描述