簡介
protobuffer是一種靈活,高效,自動化的機(jī)制,用于序列化結(jié)構(gòu)化數(shù)據(jù)。想想XML,但更小,更快,更簡單
對比XML
對于序列化結(jié)構(gòu)化數(shù)據(jù),protobuffer比XML具有許多優(yōu)點(diǎn)。protobuffer:
更簡單
3到10倍
20到100倍
?生成更易于以編程方式使用的數(shù)據(jù)訪問列
特點(diǎn)
google protobuf是跨語言的,并且自帶了一個編譯器(protoc),只需要用它進(jìn)行編譯,可以編譯成Java、python、C++、C#、Go等代碼,然后就可以直接使用,不需要再寫其他代碼,自帶有解析的代碼。
使用流程
1 在.proto文件中定義消息格式
2 用protobuf編譯器編譯.proto文件
3 用C++?對應(yīng)的protobuf API來寫或者讀消息
( 說明:.proto文件是protobuf一個重要的文件,它定義了需要序列化數(shù)據(jù)的結(jié)構(gòu)。)
消息結(jié)構(gòu)和數(shù)據(jù)類型
proto 實(shí)際上是一個?key-value結(jié)構(gòu)的類型,編碼的時候,key 和 value 是連在一起寫入二進(jìn)制數(shù)據(jù)的。解碼的時候解析器必須能跳過不認(rèn)識的字段,這樣當(dāng)同一個Proto 結(jié)構(gòu)加入新的字段時,才能保證舊協(xié)議的兼容。
proto 給每一個數(shù)據(jù)類型都定義了一個 wire_type, 不同的 wire_type 采用不同的編碼方式。
說明:發(fā)現(xiàn)簡書這里不好寫代碼的,直接在我CSDN中截圖了,希望大家理解
key 實(shí)際上是由兩個值組成的,每個字段的編號 (field_number) + 該字段的數(shù)據(jù)類型 (wire_type)。
詳細(xì)解說
1)定義一個 Message 類型
假設(shè)要定義一個搜索請求的 message 格式,其中每個搜索請求都有一個查詢字符串,你感興趣的特定結(jié)果頁數(shù)(第幾頁)以及每頁的結(jié)果數(shù)。
message SearchRequest
?{?
?requiredstringquery =1;// 查詢字符串
optional int32 page_number =2;// 第幾頁
optional int32 result_per_page =3;// 每頁的結(jié)果數(shù)
}
SearchRequest message 定義指定了三個字段(名稱/值對),每個字段對應(yīng)著要包含在 message 中的數(shù)據(jù),每個字段都有一個名稱和類型。
上面的示例中,所有字段都是?標(biāo)量類型:兩個整數(shù)(page_number 和 result_per_page)和一個字符串(query)。(還可以為字段指定復(fù)合類型,包括枚舉 和其它的 message 類型。)
建議每個 .proto 文件包含盡可能少的 message 類型。
分配字段編號
message 定義中的每個字段都有唯一編號。這些數(shù)字以 message 二進(jìn)制格式標(biāo)識你的字段,并且一旦你的 message 被使用,這些編號就無法再更改。
請注意,1 到 15 范圍內(nèi)的字段編號需要一個字節(jié)進(jìn)行編碼,編碼結(jié)果將同時包含編號和類型。16 到 2047 范圍內(nèi)的字段編號占用兩個字節(jié)。因此,你應(yīng)該為非常頻繁出現(xiàn)的 message 元素保留字段編號 1 到 15。請記住為將來可能添加的常用元素預(yù)留出一些空間。
字段編號范圍:以指定的最小字段數(shù)為1,最大字段數(shù)為536,870,911。
(你也不能使用 19000 到 19999 范圍內(nèi)的數(shù)字,因?yàn)樗鼈兪菫?Protocol Buffers 的實(shí)現(xiàn)保留的 - 如果你使用這些保留數(shù)字之一,編譯器會報錯你的 .proto)
指定字段規(guī)則
指定的 message 字段可以是下面幾種情況之一:
required: 格式良好的 message必須包含該字段一次。
optional: 格式良好的 message 可以包含該字段零次或一次(不超過一次)。
repeated: 該字段可以在格式良好的消息中重復(fù)任意多次(包括零)。其中重復(fù)值的順序會被保留。
新代碼應(yīng)使用特殊選項(xiàng)[packed = true] 來獲得更高效的編碼,如:
repeated int32 samples =4[packed=true];
.proto 文件將生成什么?
在 .proto 上運(yùn)行 protocol buffer 編譯器時,編譯器將會生成所需語言的代碼,這些代碼可以操作文件中描述的message 類型,包括獲取和設(shè)置字段值、將 message 序列化為輸出流、以及從輸入流中解析出 message。
對于 C++,編譯器從每個 .proto 生成一個 .h 和 .cc 文件,其中包含文件中描述的每種 message 類型對應(yīng)的類。
標(biāo)量值類型
定義 protocol 格式
? 需要從 .proto 文件開始,.proto 文件中的定義很:為要序列化的每個數(shù)據(jù)結(jié)構(gòu)添加 message 定義,然后為 message 中的每個字段指定名稱和類型。下面就是定義相關(guān) message 的 .proto 文件:

?required:必須提供該字段的值,否則該消息將被視為“未初始化”。如果是在調(diào)試模式下編譯 libprotobuf,則序列化一個未初始化的 message 將將導(dǎo)致斷言失敗。在優(yōu)化的構(gòu)建中,將跳過檢查并始終寫入消息。
optional: 可以設(shè)置也可以不設(shè)置該字段。如果未設(shè)置可選字段值,則使用默認(rèn)值。對于簡單類型,你可以指定自己的默認(rèn)值,就像我們在示例中為電話號碼類型所做的那樣。否則,使用系統(tǒng)默認(rèn)值:數(shù)字類型為 0,字符串為空字符串,bools 為 false。對于嵌入 message,默認(rèn)值始終是消息的 “默認(rèn)實(shí)例” 或 “原型”,其中沒有設(shè)置任何字段。。
repeated: 該字段可以重復(fù)任意次數(shù)(包括零次)。重復(fù)值的順序?qū)⒈A粼?protocol buffer 中??梢詫?repeated 字段視為動態(tài)大小的數(shù)組。
標(biāo)準(zhǔn) Message 方法
每個 message 類還包含許多其他方法,可用于檢查或操作整個 message,包括:

解析和序列化
每個 protocol buffer 類都有使用 protocol buffer 二進(jìn)制格式 讀寫所選類型 message 的方法。包括:

希望對你有幫助。