ProtoBuffer是由谷歌研發的對象序列化和反序列化的開源工具,ProtoBuffer和Xml類似,都是數據描述工具,后者使用更為廣泛,前者Google內部使用且具有更高的效率。該工具安裝和使用都很簡單,查看了下網上貼代碼的居多,這里整理下以便以后使用。
1.安裝
sudo apt-get install protobuf-compiler
2.說明文檔
語法說明請參考:
[1]. Protocol Buffer技術詳解(語言規范)
簡單例子請參考:
[1]. Google Protocol Buffers淺析(一,二,三,四)(windows下的使用,linux用戶可參考其語法)
3. Eclipse CDT下使用ProtoBuffer
編寫一個用戶信息列表的描述,並完成對象序列化和反序列化操作。
a. 新建項目
建立一個新的c++ project,命名為TestPbuffer,並建立文件夾src, data, proto:
b. 數據描述
在目錄proto下添加代碼,person.proto,並編輯加入以下代碼:
message Person{ required string name = 1; required int32 age = 2; optional string email = 3; enum PhoneType{ HOME = 1; MOBILE = 2; WORK = 3; } message Phone{ required int64 id = 1; optional PhoneType type = 2 [default = HOME]; } repeated Phone phoneNum = 4; } message UserList{ required string name = 1; repeated Person users = 2; }
Proto文件與xml類似,能夠對數據進行格式化的描述,以上的數據描述完成了用戶信息記錄列表的定義。具體含義請參閱:Protocol Buffer技術詳解(語言規范)
c. 生成c++代碼
在控制台下跳轉到目錄proto,然后執行以下編譯命令:
$ protoc person.proto --cpp_out=../src/
生成的c++文件person.pb.h和person.pb.cc存放在src下。對象的序列化和反序列化就是通過這兩個文件完成操作了。
d. 配置Include和Link
右擊project的Propertise->C++ Build->Setting,具體配置如下圖所示:
e.編寫測試程序
在src目錄下添加TestProtoBuffer.cpp文件,並添加以下代碼:
//============================================================================ // Name : TestPbuffer.cpp // Author : xiankai.chen // Version : // Copyright : xiankai.chen@qq.com // Description : Test proto buffer in C++, Ansi-style //============================================================================ #include <iostream> #include <fstream> #include <string> #include "person.pb.h" using namespace std; int main() { /*write object to file*/ UserList user_list; user_list.set_name("用戶列表"); //add person 1 Person* person; Person::Phone *phone; person = user_list.add_users(); person->set_name("cxk"); person->set_age(30); person->set_email("xiankai.chen@qq.com"); phone = person->add_phonenum(); phone->set_type(Person::HOME); phone->set_id(13418638333); phone = person->add_phonenum(); phone->set_type(Person::MOBILE); phone->set_id(13234444555); //add person 2 person = user_list.add_users(); person->set_name("lgm"); person->set_age(30); person->set_email("77015684@gmail.com"); phone = person->add_phonenum(); phone->set_type(Person::HOME); phone->set_id(13344655445); phone = person->add_phonenum(); phone->set_type(Person::MOBILE); phone->set_id(13765546785); fstream output("./data/myinfo.dat",ios::out|ios::binary); user_list.SerializeToOstream(&output); output.close(); output.clear(); /*read object from file*/ fstream input("./data/myinfo.dat",ios::in|ios::binary); UserList userlist_in; if(!userlist_in.ParseFromIstream(&input)) { cout<<"parse error"<<endl; return -1; } cout<<"userlist name: "<< userlist_in.name() <<endl; for(int i = 0; i < userlist_in.users_size(); i++) { cout<<"person["<<i<<"] name:"<< userlist_in.users(i).name()<< endl; cout<<"person["<<i<<"] age:"<< userlist_in.users(i).age()<< endl; cout<<"person["<<i<<"]email:"<< userlist_in.users(i).email()<< endl; for(int j = 0; j < userlist_in.users(i).phonenum_size(); j++) { cout<<"person["<<i<<"] phonenum["<<j<<"] type:"<< userlist_in.users(i).phonenum(j).type()<< endl; cout<<"person["<<i<<"] phonenum["<<j<<"] no:"<< userlist_in.users(i).phonenum(j).id()<< endl; } } input.close(); input.clear(); return 0; }
f.執行測試結果
如下所示
userlist name: 用戶列表 person[0] name:cxk person[0] age:30 person[0]email:xiankai.chen@qq.com person[0] phonenum[0] type:1 person[0] phonenum[0] no:13418638333 person[0] phonenum[1] type:2 person[0] phonenum[1] no:13234444555 person[1] name:lgm person[1] age:30 person[1]email:77015684@gmail.com person[1] phonenum[0] type:1 person[1] phonenum[0] no:13344655445 person[1] phonenum[1] type:2 person[1] phonenum[1] no:13765546785
g. 工程代碼
下載鏈接:TestPbuffer.tar.gz