Protocol Buffers(Protobuf)開發者指南---概覽

歡迎來到protocol buffers的開發者指南文檔,protocol buffers是一個與編程語言無關‘、系統平臺無關、可擴展的結構化數據序列化/反序列化工具,適用於通訊協議,數據存儲等場合。

ps:爲了方便拼寫,下文的protobuf就是指protocol buffers。

本文檔的面向讀者是:希望使用protobuf的 Java、C++、Python的開發者。此概覽將向您介紹如何開始使用protobuf,然後您可以跟着示例進行學習,或者深入瞭解protobuf的編碼方式。API參考文檔同樣提供了此三種語言的版本,而且爲了更好的編寫.proto文件提供了語言指導、風格指導文檔。

-------------------------------------------------------------------------------------小小的分割線----------------------------------------------------------------------------------------------------------

protobuf是什麼?

protobuf 是一個靈活、高效,使用自動化機制的結構化數據序列工具,類似於XML,但比XML更小巧、更快、而且也更簡單。只需要定義一次數據結構,你就可以使用代碼生成器生成各種編程語言和各種流式文件的結構化讀取和寫入。甚至可以在無需重新編譯部署新程序的情況下更新新的結構化數據。


他們是如何工作的?

你需要在protobuf信息文件內(.proto)指定你需要序列化的信息是什麼樣的結構。每個protubuf信息是一小段邏輯記錄,包含一系列的“鍵--值”組合。這有一個定義了個人信息的protobuf信息文件例子!

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

如你所見,信息格式很簡單,每個消息類型都有一個或多個唯一的字段,每個字段都有一個名字和值類型,值的類型可以是數字(整數或浮點數),邏輯值,字符串,字節,或者其他的自定義protobuf消息類型(就像上面的例子一樣PhoneNubmer的PhoneType類型是自定的protobuf消息類型),允許您使用多層次的結構體,你可以指定optional(可選)、required(必須)、repeated(重複),需要更多的關於.proto信息文件的編寫幫助請查看protobuf語言指南

一旦你定義了自己的消息格式(message),你就可以運行protobuf編譯器,將你的 .proto 文件編譯成特定語言的類。這些類提供了簡單的方法訪問每個字段(類似query() 和 set_query() ),就像訪問類的方法一樣將結構序列化或反序列化。例如你可以選擇C++語言,運行編譯如上的協議文件生成叫做Person的類 。隨後你就可以在應用中使用這個類來序列化的讀取信息。你可以這麼寫代碼(此過程叫做序列化):

Person person;
person.set_name("John Doe");
person.set_id(1234);
person.set_email("[email protected]");
fstream output("myfile", ios::out | ios::binary);
person.SerializeToOstream(&output);
然後你可以這樣讀取已經序列化的信息(這個過程叫做反序列化):

fstream input("myfile", ios::in | ios::binary);
Person person;
person.ParseFromIstream(&input);
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;

你可以在不影響向後兼容的情況下隨意給數據結構增加字段,舊有的數據會忽略新的字段。所以如果使用protobuf作爲通信協議,你可以無須擔心破壞現有代碼的情況下擴展協議。

你可以在此找到完整的API參考 API Reference section, 關於Protobuf如何編碼可以在此找到完整的文檔Protocol Buffer Encoding.


爲何不使用XML?

protobuf擁有比XML更多高級的序列化特點:

  • 更簡單
  • 小3-10倍
  • 快20-100倍
  • 更少的歧義
  • 可以方便的生成數據存取類,易於使用
例如,讓我們看看如何在XML中建模Person的name和email字段:
<person>
    <name>John Doe</name>
    <email>[email protected]</email>
</person>

對應的ProtocolBuffer報文則如下:此爲protobuf的文本表示
這不是正常時使用的二進制數據
person {
    name: "John Doe"
    email: "[email protected]"
}

當這個報文編碼到protobuf的二進制格式時(上面的文本僅用於調試和編輯),它只需要28字節和100-200ns的解析時間。而XML的版本需要69字節(除去空白)和 5000-10000ns的解析時間。

當然,操作Protobuf也很簡單:
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;
而XML的你需要:
cout << "Name: "
     << person.getElementsByTagName("name")->item(0)->innerText()
     << endl;
cout << "E-mail: "
     << person.getElementsByTagName("email")->item(0)->innerText()
     << end;

當然,Protobuf並不是在任何時候都比XML更合適,例如Protobuf無法對一個基於標記文本的文檔建模,因爲你根本沒法方便的在文本中插入結構。另外,XML是便於人類閱讀和編輯的,而Protobuf則不是。還有XML是自解釋的,而Protobuf僅在你擁有報文格式定義的 .proto 文件時纔有意義。


感覺這個解決方案很不錯,非常適合我,應該如何開始呢?

點擊下載protobuf包 – 這包含了 Java、Python、C++的protobuf編譯器源碼,如何 生成你需要的IO類。構建和安裝protobuf編譯器,請查閱README的文檔。
一旦都準備好了的話,嘗試跟隨你選擇的語言的指導例程,它將一步步的指導你如何使用protobuf構建應用程序!

關於Protobuf的一點歷史
protobuf最初是在Google開發的,用以解決索引服務器的請求、響應協議。在使用ProtocolBuffer之前,有一種格式用以處理請求和響應數據的編碼和解碼,並且支持多種版本的協議。而這最終導致了醜陋的代碼,例如:
 if (version == 3) {
   ...
 } else if (version > 4) {
   if (version == 5) {
     ...
   }
   ...
 }
通信協議因此變得越來越複雜,因爲開發者必須確保,發出請求的人和接受請求的人必須同時兼容,並且在一方開始使用新協議時,另外一方也要可以接受。

Protobuf設計用於解決這一類問題:

  • 很方便引入新字段,而中間服務器可以忽略這些字段,直接傳遞過去而無需理解所有的字段。
  • 格式可以自描述,並且可以在多種語言中使用(C++、Java等)

然而用戶仍然需要手寫解析代碼。

隨着系統的演化,他需要一些其他的功能:

  • 自動生成編碼和解碼代碼,而無需自己編寫解析器。
  • 除了用於簡短的RPC(Remote Procedure Call)請求,人們使用protobuf來做數據存儲格式(例如BitTable)。
  • RPC服務器接口可以作爲 .proto 文件來描述,而通過protobuf的編譯器生成存取(stub)類供用戶實現服務器接口。

protobuf現在已經是Google的混合語言數據標準了,現在已經正在使用的有超過48,162種報文格式定義和超過 12,183個 .proto 文件。他們用於RPC系統和持續數據存儲系統。


原文地址:https://developers.google.com/protocol-buffers/docs/overview

參考翻譯自:小狼.exe的博客:http://blog.163.com/jiang_tao_2010/blog/static/12112689020114305013458/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章