Google Protocol Buffers 簡(jiǎn)介(一)

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 用戶編譯安裝如下:

  1. 打開(kāi) protobuf-2.6.1/vsprojects/protobuf.sln兼都。
  2. 將項(xiàng)目 libprotobuf 設(shè)置為啟動(dòng)項(xiàng)目。
  3. 編譯 sln稽寒,Debug 模式和 Release 模式都編譯一下扮碧。
  4. 在 vsprojects/Debug 和 vsprojects/Release 目錄下會(huì)有 libprotobuf.lib、libprotobuf-lite.lib瓦胎、libprotoc.lib 和 protoc.exe文件芬萍。
  5. 新建一個(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í)例齿诞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市骂租,隨后出現(xiàn)的幾起案子掌挚,更是在濱河造成了極大的恐慌,老刑警劉巖菩咨,帶你破解...
    沈念sama閱讀 212,332評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡抽米,警方通過(guò)查閱死者的電腦和手機(jī)特占,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)云茸,“玉大人是目,你說(shuō)我怎么就攤上這事”贽啵” “怎么了懊纳?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,812評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)亡容。 經(jīng)常有香客問(wèn)我嗤疯,道長(zhǎng),這世上最難降的妖魔是什么闺兢? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,607評(píng)論 1 284
  • 正文 為了忘掉前任茂缚,我火速辦了婚禮,結(jié)果婚禮上屋谭,老公的妹妹穿的比我還像新娘脚囊。我一直安慰自己,他們只是感情好桐磁,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,728評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布悔耘。 她就那樣靜靜地躺著,像睡著了一般我擂。 火紅的嫁衣襯著肌膚如雪衬以。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,919評(píng)論 1 290
  • 那天扶踊,我揣著相機(jī)與錄音泄鹏,去河邊找鬼。 笑死秧耗,一個(gè)胖子當(dāng)著我的面吹牛备籽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播分井,決...
    沈念sama閱讀 39,071評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼车猬,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了尺锚?” 一聲冷哼從身側(cè)響起珠闰,我...
    開(kāi)封第一講書(shū)人閱讀 37,802評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瘫辩,沒(méi)想到半個(gè)月后伏嗜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體坛悉,經(jīng)...
    沈念sama閱讀 44,256評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,576評(píng)論 2 327
  • 正文 我和宋清朗相戀三年承绸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了裸影。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,712評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡军熏,死狀恐怖轩猩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情荡澎,我是刑警寧澤均践,帶...
    沈念sama閱讀 34,389評(píng)論 4 332
  • 正文 年R本政府宣布,位于F島的核電站摩幔,受9級(jí)特大地震影響彤委,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜热鞍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,032評(píng)論 3 316
  • 文/蒙蒙 一葫慎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薇宠,春花似錦偷办、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至回梧,卻和暖如春废岂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狱意。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工湖苞, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人详囤。 一個(gè)月前我還...
    沈念sama閱讀 46,473評(píng)論 2 360
  • 正文 我出身青樓财骨,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親藏姐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子隆箩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,606評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容