Google Protocol Buffers是什么
Google Protocol Buffers 簡(jiǎn)稱(chēng) Protobuf陨倡,它提供了一種靈活宛逗、高效扒腕、自動(dòng)序列化結(jié)構(gòu)數(shù)據(jù)的機(jī)制,可以聯(lián)想 XML待侵,但是比 XML 更小、更快姨裸、更簡(jiǎn)單秧倾。僅需要自定義一次你所需的數(shù)據(jù)格式,然后用戶就可以使用 Protobuf 編譯器自動(dòng)生成各種語(yǔ)言的源碼傀缩,方便的讀寫(xiě)用戶自定義的格式化的數(shù)據(jù)那先。與語(yǔ)言無(wú)關(guān),與平臺(tái)無(wú)關(guān)赡艰,還可以在不破壞原數(shù)據(jù)格式的基礎(chǔ)上售淡,依據(jù)老的數(shù)據(jù)格式,更新現(xiàn)有的數(shù)據(jù)格式慷垮。
Protobuf 的特點(diǎn)簡(jiǎn)單總結(jié)如下幾點(diǎn):
- 作用與 XML揖闸、json 類(lèi)似,但它是二進(jìn)制格式料身,性能好汤纸、效率高
- 代碼生成機(jī)制,易于使用
- 解析速度快
- 支持多種語(yǔ)言
- 向后兼容芹血、向前兼容
- 缺點(diǎn):可讀性差
目前贮泞,Protobuf 提供了兩個(gè)大版本: 2.x 版本和 3.x 版本。 2.x 版本最新的版本是 2.6.1幔烛,支持 C++啃擦、Java 和 Python 三種語(yǔ)言的API。 3.x 版本最新的版本是 3.0.0-beta-1饿悬,支持 C++议惰、Java、Python乡恕、Ruby、JavaNano俯萎、Objective-x 和 C# 這幾種語(yǔ)言的 API傲宜。
Protobuf 如何工作
用戶在 .proto 文件中定義 message
來(lái)指定所需要序列化的數(shù)據(jù)格式。每一個(gè) message
都是一個(gè)小的信息邏輯單元夫啊,包含一系列的 name-value 值對(duì)函卒。下面舉例來(lái)說(shuō)明一個(gè)簡(jiǎn)單的 .proto 文件,它定義了一條包含 Person 信息的 message
撇眯。
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;
}
從以上代碼來(lái)看报嵌,message
格式非常簡(jiǎn)單虱咧。每種類(lèi)型的 message
包含一個(gè)或者多個(gè)唯一編碼字段,每個(gè)字段由名稱(chēng)和值類(lèi)型組成锚国,值類(lèi)型可以是數(shù)字(整形或者浮點(diǎn)型)腕巡、布爾值、字符串血筑、原始字節(jié)绘沉,甚至是其他的 message
(如上例所示)。Protobuf 允許 message
中包含 message
豺总,以達(dá)到分層嵌套车伞。message
中可以定義 optional 字段、required 字段和 repeated 字段喻喳。
定義好 message
后另玖,運(yùn)行 Protobuf 編譯器編譯 .proto 文件,就可以生成存取數(shù)據(jù)的相關(guān)類(lèi)表伦。這些類(lèi)包括簡(jiǎn)單的設(shè)置及讀取字段(比如 name()
和 set_name()
)的方法谦去,也包括整個(gè)數(shù)據(jù)結(jié)構(gòu)的 message
和原始字節(jié)之間的序列化/反序列化的轉(zhuǎn)換方法。舉個(gè)例子绑榴,如果你選擇的是 C++ 語(yǔ)言哪轿,運(yùn)行 Protobuf 編譯器編譯以上 .proto 文件生成 Person 類(lèi)。你就能使用這個(gè)類(lèi)去填充翔怎、序列化窃诉、檢索 Person message
。如下代碼:
Person person;
person.set_name("zebra");
person.set_id(123);
person.set_email("zebra@example.com");
fstream output("myfile", ios::out | ios::binary);
person.SerializeToOstream(&output);
接下來(lái)赤套,用如下代碼來(lái)讀取 message
:
fstream input("myfile", ios::in | ios::binary);
Person person;
person.ParseFromIstream(&input);
cout << "Name: " << person.name() << endl;
cout << "E-mail" << person.email() << endl;
Protobuf 是易于擴(kuò)展的飘痛,可以向后兼容,我們可以在 message
中添加新字段容握,在解析的時(shí)候宣脉,老版本的數(shù)據(jù)就會(huì)忽略新增加的字段。因此剔氏,如果現(xiàn)有通訊協(xié)議使用 Protobuf 做為其數(shù)據(jù)格式塑猖,我們可以直接擴(kuò)展該通訊協(xié)議,而不必?fù)?dān)心著將會(huì)破壞現(xiàn)有的代碼谈跛。關(guān)于使用 .proto 文件生成目標(biāo)代碼羊苟,后面將會(huì)介紹。
如何使用 Protobuf
我們使用 Protobuf 和 C++ 開(kāi)發(fā)一個(gè)簡(jiǎn)單的例子程序感憾,該程序?qū)崿F(xiàn)將一些結(jié)構(gòu)化數(shù)據(jù)寫(xiě)入文件和讀取文件蜡励。
首先下載 Protobuf 2.6.1 源碼。 下載頁(yè)面:Protobuf github
編譯安裝 Protobuf
Linux用戶編譯安裝如下:
tar -xzf protobuf-2.6.1.tar.gz
cd protobuf-2.6.1
./autogen
./configure --prefix=$INSTALL_DIR
make
make check
make install
如有問(wèn)題,請(qǐng)認(rèn)真閱讀 protobuf-2.6.1/README.md 和 protobuf-2.6.1/INSTALL.txt凉倚。
windows 用戶編譯安裝如下:
- 打開(kāi) protobuf-2.6.1/vsprojects/protobuf.sln兼都。
- 將項(xiàng)目 libprotobuf 設(shè)置為啟動(dòng)項(xiàng)目。
- 編譯 sln稽寒,Debug 模式和 Release 模式都編譯一下扮碧。
- 在 vsprojects/Debug 和 vsprojects/Release 目錄下會(huì)有 libprotobuf.lib、libprotobuf-lite.lib瓦胎、libprotoc.lib 和 protoc.exe文件芬萍。
- 新建一個(gè)名為 “Install” 的文件夾,在 “Install” 目錄下再新建三個(gè)文件夾搔啊,分別是 “bin”柬祠、“include” 和 “l(fā)ib”。將編譯生成的 protoc.exe 拷貝到 “bin” 目錄下负芋,將編譯生成的 lib 庫(kù)文件拷貝到 “l(fā)ib” 目錄下漫蛔,將 protobuf/src 下的源文件拷貝 “include” 目錄下。
書(shū)寫(xiě) .proto 文件
定義一個(gè)關(guān)于個(gè)人信息的 .proto 文件旧蛾,內(nèi)容如下:
package tutorial;
message Person
{
required string name = 1;
required int32 age = 2;
optional string email = 3;
}
編譯 .proto 文件莽龟,生成 C++ 文件
使用 cmd 運(yùn)行 proto.exe 生成我們的目標(biāo)語(yǔ)言格式(C++)。命令行格式如下:
protoc.exe -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/person.proto
-I:指定 .proto 文件所在的路徑锨天。
--cpp_out:指定生成的目標(biāo)文件存在的路徑毯盈。
最后的參數(shù)是你需要生成的 .proto 文件名。
上例會(huì)生成 person.pb.h 和 person.pb.cc 的文件病袄。person.pb.h 定義了 C++ 類(lèi)的頭文件搂赋,person.pb.cc 是 C++ 類(lèi)的實(shí)現(xiàn)文件。
使用 Protobuf 庫(kù)提供的 API 來(lái)編寫(xiě)應(yīng)用程序益缠。
使用 Protobuf 庫(kù)來(lái)編寫(xiě)應(yīng)用程序時(shí)脑奠,需要包含 Protobuf 的頭文件,還需要鏈接庫(kù)文件幅慌。person.pb.h 頭文件定義了設(shè)置和讀取字段的方法宋欺,還有序列化和反序列化的方法,可以很方便的調(diào)用胰伍,可以參考上一章節(jié)的實(shí)例齿诞。