每週一薦:Google的序列化框架Protobuf

作  者:david++
發佈時間:2012/05/31 21:00
轉載地址:http://game-lab.org/?p=313

1. 簡介

Protocol Buffers是Google的一個序列化框架,可以非常方便地把程序中用到的結構化數據轉換成二進制字節塊,並且它對於結構化數據的編碼也是比較特殊的,一個字節最高位(MSB)代表下一個字節是否和當前這個字節構成一個數據。因此,Protobuf的存儲效率比較高,數值小的佔的字節數少,數值大的佔的相應的字節數就比較多。

Protobuf對於程序中對應的結構會有一份結構描述文件。可以通過它提供的protoc生成指定類型的代碼(C++、Java等),對於網絡協議的編寫有極大的方便,一處定義,然後可以轉換成多種語言的代碼。同時,還支持RPC。

以前在項目中也寫過序列化相關的代碼,最質樸的BYTE、WORD、DWORD、QWORD或者對應的數組,並且可以非常方便地對於STL容器進行序列化,容器的嵌套也不在話下(如:std::map<DWORD, std::vector<…> >)。但對於數據結構的變動,就必須自己進行版本化控制。而Protobuf對於結構每一個字段都有一個標識,只要保證按着它的添加規則來(具體參考下面的鏈接),版本控制基本上就都可以靠Protobuf搞定了。

2. 一個簡單的例子

step1:寫一個example.proto文件

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

step2:使用protoc編譯,生成指定程序類型的代碼(example.pb.h, example.pb.cc)

protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/example.proto

step3:使用生成的代碼
序列化代碼片段:

複製代碼
Person person;
person.set_id(123);
person.set_name("Bob");
person.set_email("[email protected]");
 
fstream out("person.pb", ios::out | ios::binary | ios::trunc);
person.SerializeToOstream(&out);
out.close();
複製代碼

 

反序列化代碼片段:

複製代碼
Person person;
fstream in("person.pb", ios::in | ios::binary);
if (!person.ParseFromIstream(&in)) {
  cerr << "Failed to parse person.pb." << endl;
  exit(1);
}
 
cout << "ID: " << person.id() << endl;
cout << "name: " << person.name() << endl;
if (person.has_email()) {
  cout << "e-mail: " << person.email() << endl;
}
複製代碼

3. 更多參考資料

  1. Protobuf下載
  2. Protobuf文檔
  3. Protobuf編碼規則
  4. Protocol Buffer Basics: C++

2012/05/31 20:58 於上海

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