亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Potocol Buffer詳解

2019-11-15 00:54:13
字體:
來源:轉載
供稿:網友
Potocol Buffer詳解PRotocol安裝及使用

上一篇博文介紹了一個綜合案例,這篇將詳細介紹protocol buffer。

為什么使用protocol buffer?
  1. java默認序列化效率較低。
  2. apache的thrift方案并無明顯優勢,但是使用成本較高,安裝等較為麻煩。
  3. 雖然PB不支持map,但是我們的應用中map用的較少,即使使用了存儲的數據量也較少,可以轉化為list方案進行存儲。
  4. 以前我玩過PB,這很關鍵,當你有某方面的經驗時能較輕松的應對一些意外情況。
  5. 保證同一消息報文新舊版本之間的兼容性
  6. 使用SOAP協議(WebService)作為消息報文的格式載體,由該方式生成的報文是基于文本格式的,同時還存在大量的xml描述信息,因此將會大大增加網絡IO的負擔。
怎么安裝?

首先,要使用protocolbuffer得保證maven安裝成功,maven的下載地址:http://maven.apache.org/download.cgi。

1.解壓完之后請將maven的bin目錄配置到你的環境變量當中。

2.請確保你的JAVA_HOME的變量是指向你的JDK的主目錄,如果你的系統變量中沒有JAVA_HOME這一項,請點擊新建添加。

3.打開命令行,輸入“mvn--version”如果輸出正確則表示安裝成功

安裝完maven之后就要進行protocolbuffer的安裝了,下載地址:http://code.google.com/p/protobuf/downloads/list。下載protobuf-2.4.1.zip和protoc-2.4.1-win32.zip兩個包。

1.解壓完成之后有兩種選擇,第一:將protoc-2.4.1-win32中的protoc.exe所在的目錄配置到環境變量當中,第二:將protoc.exe拷貝到c:/windows/system32目錄下,這里推薦第二種做法。

2.將proto.exe文件拷貝到解壓后的protobuf-2.4.1/src目錄中.

3.進入protobuf-2.4.1/java目錄執行mvnpackage命令編輯該包,系統將會在target目錄中生成protobuf-java-2.4.1.jar文件(注意運行時需要聯網,首次安裝可能需要一定的時間)。

4.假設你的數據文件目錄在XXX/data目錄,把上一步生成的jar拷貝到該目錄中即可。

5.進入XXX/protobuf-2.4.1/examples目錄,可以看到addressbook.proto文件,在命令行中執行protoc--java_out=.addressbook.proto命令(特別注意.Addressbook.proto中間的空格,我第一次安裝就因為沒注意而反復失?。?,如果生成com文件夾并且最終生成AddressBookProtos類則說明安裝成功。

6.打開eclipse,選擇windows-->preferences-->java-->InstalledJREs編輯你默認的java源碼包,并將上面所提到的protobuf-java-2.4.1.jar文件添加進去。

以上內容均摘抄與網絡,經驗證可正確安裝Protocol Buffer(語言規范)

以下文章摘抄http://www.49028c.com/stephen-liu74/archive/2013/01/02/2841485.html

一.Protobuf 的優點

Protobuf 有如 XML,不過它更小、更快、也更簡單。你可以定義自己的數據結構,然后使用代碼生成器生成的代碼來讀寫這個數據結構。你甚至可以在無需重新部署程序的情況下更新數據結構。只需使用 Protobuf 對數據結構進行一次描述,即可利用各種不同語言或從各種不同數據流中對你的結構化數據輕松讀寫。

它有一個非常棒的特性,即“向后”兼容性好,人們不必破壞已部署的、依靠“老”數據格式的程序就可以對數據結構進行升級。這樣您的程序就可以不必擔心因為消息結構的改變而造成的大規模的代碼重構或者遷移的問題。因為添加新的消息中的 field 并不會引起已經發布的程序的任何改變。

Protobuf 語義更清晰,無需類似 XML 解析器的東西(因為 Protobuf 編譯器會將 .proto 文件編譯生成對應的數據訪問類以對 Protobuf 數據進行序列化、反序列化操作)。

使用 Protobuf 無需學習復雜的文檔對象模型,Protobuf 的編程模式比較友好,簡單易學,同時它擁有良好的文檔和示例,對于喜歡簡單事物的人們而言,Protobuf 比其他的技術更加有吸引力。

二、定義第一個Protocol Buffer消息。 創建擴展名為.proto的文件,如:MyMessage.proto,并將以下內容存入該文件中。 message LogonReqMessage { required int64 acctID = 1; required string passwd = 2; } 這里將給出以上消息定義的關鍵性說明。 1. message是消息定義的關鍵字,等同于C++中的struct/class,或是Java中的class。 2. LogonReqMessage為消息的名字,等同于結構體名或類名。 3. required前綴表示該字段為必要字段,既在序列化和反序列化之前該字段必須已經被賦值。與此同時,在Protocol Buffer中還存在另外兩個類似的關鍵字,optional和repeated,帶有這兩種限定符的消息字段則沒有required字段這樣的限制。相比于optional,repeated主要用于表示數組字段。具體的使用方式在后面的用例中均會一一列出。 4. int64和string分別表示長整型和字符串型的消息字段,在Protocol Buffer中存在一張類型對照表,既Protocol Buffer中的數據類型與其他編程語言(C++/Java)中所用類型的對照。該對照表中還將給出在不同的數據場景下,哪種類型更為高效。該對照表將在后面給出。 5. acctID和passwd分別表示消息字段名,等同于Java中的域變量名,或是C++中的成員變量名。 6. 標簽數字12則表示不同的字段在序列化后的二進制數據中的布局位置。在該例中,passwd字段編碼后的數據一定位于acctID之后。需要注意的是該值在同一message中不能重復。另外,對于Protocol Buffer而言,標簽值為1到15的字段在編碼時可以得到優化,既標簽值和類型信息僅占有一個byte,標簽范圍是16到2047的將占有兩個bytes,而Protocol Buffer可以支持的字段數量則為2的29次方減一。有鑒于此,我們在設計消息結構時,可以盡可能考慮讓repeated類型的字段標簽位于1到15之間,這樣便可以有效的節省編碼后的字節數量。 三、定義第二個(含有枚舉字段)Protocol Buffer消息。 //在定義Protocol Buffer的消息時,可以使用和C++/Java代碼同樣的方式添加注釋。 enum UserStatus { OFFLINE = 0;//表示處于離線狀態的用戶 ONLINE = 1;//表示處于在線狀態的用戶 } message UserInfo { required int64 acctID = 1; required string name = 2; required UserStatus status = 3; } 這里將給出以上消息定義的關鍵性說明(僅包括上一小節中沒有描述的)。 1. enum是枚舉類型定義的關鍵字,等同于C++/Java中的enum。 2. UserStatus為枚舉的名字。 3. 和C++/Java中的枚舉不同的是,枚舉值之間的分隔符是分號,而不是逗號。 4. OFFLINE/ONLINE為枚舉值。 5. 0和1表示枚舉值所對應的實際整型值,和C/C++一樣,可以為枚舉值指定任意整型值,而無需總是從0開始定義。如: enum OperationCode { LOGON_REQ_CODE = 101; LOGOUT_REQ_CODE = 102; RETRIEVE_BUDDIES_REQ_CODE = 103; LOGON_RESP_CODE = 1001; LOGOUT_RESP_CODE = 1002; RETRIEVE_BUDDIES_RESP_CODE = 1003; } 四、定義第三個(含有嵌套消息字段)Protocol Buffer消息。 我們可以在同一個.proto文件中定義多個message,這樣便可以很容易的實現嵌套消息的定義。如: enum UserStatus { OFFLINE = 0; ONLINE = 1; } message UserInfo { required int64 acctID = 1; required string name = 2; required UserStatus status = 3; } message LogonRespMessage { required LoginResult logonResult = 1; required UserInfo userInfo = 2; } 這里將給出以上消息定義的關鍵性說明(僅包括上兩小節中沒有描述的)。 1. LogonRespMessage消息的定義中包含另外一個消息類型作為其字段,如UserInfo userInfo。 2. 上例中的UserInfo和LogonRespMessage被定義在同一個.proto文件中,那么我們是否可以包含在其他.proto文件中定義的message呢?Protocol Buffer提供了另外一個關鍵字import,這樣我們便可以將很多通用的message定義在同一個.proto文件中,而其他消息定義文件可以通過import的方式將該文件中定義的消息包含進來,如:import"myproject/CommonMessages.proto" 五、限定符(required/optional/repeated)的基本規則。 1. 在每個消息中必須至少留有一個required類型的字段。 2. 每個消息中可以包含0個或多個optional類型的字段。 3. repeated表示的字段可以包含0個或多個數據。需要說明的是,這一點有別于C++/Java中的數組,因為后兩者中的數組必須包含至少一個元素。 4. 如果打算在原有消息協議中添加新的字段,同時還要保證老版本的程序能夠正常讀取或寫入,那么對于新添加的字段必須是optional或repeated。道理非常簡單,老版本程序無法讀取或寫入新增的required限定符的字段。 六、類型對照表。

.proto TypeNotesC++ TypeJava Type
doubledoubledouble
floatfloatfloat
int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.int32int
int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.int64long
uint32Uses variable-length encoding.uint32int
uint64Uses variable-length encoding.uint64long
sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.int32int
sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.int64long
fixed32Always four bytes. More efficient than uint32 if values are often greater than 228.uint32int
fixed64Always eight bytes. More efficient than uint64 if values are often greater than 256.uint64long
sfixed32Always four bytes.int32int
sfixed64Always eight bytes.int64long
boolboolboolean
stringA string must always contain UTF-8 encoded or 7-bit ASCII text.stringString
bytesMay contain any arbitrary sequence of bytes.stringByteString

七、Protocol Buffer消息升級原則。 在實際的開發中會存在這樣一種應用場景,既消息格式因為某些需求的變化而不得不進行必要的升級,但是有些使用原有消息格式的應用程序暫時又不能被立刻升級,這便要求我們在升級消息格式時要遵守一定的規則,從而可以保證基于新老消息格式的新老程序同時運行。規則如下: 1. 不要修改已經存在字段的標簽號。 2. 任何新添加的字段必須是optional和repeated限定符,否則無法保證新老程序在互相傳遞消息時的消息兼容性。 3. 在原有的消息中,不能移除已經存在的required字段,optional和repeated類型的字段可以被移除,但是他們之前使用的標簽號必須被保留,不能被新的字段重用。 4. int32、uint32、int64、uint64和bool等類型之間是兼容的,sint32和sint64是兼容的,string和bytes是兼容的,fixed32和sfixed32,以及fixed64和sfixed64之間是兼容的,這意味著如果想修改原有字段的類型時,為了保證兼容性,只能將其修改為與其原有類型兼容的類型,否則就將打破新老消息格式的兼容性。 5. optional和repeated限定符也是相互兼容的。 八、Packages。 我們可以在.proto文件中定義包名,如: packageourproject.lyphone; 該包名在生成對應的C++文件時,將被替換為名字空間名稱,既namespace ourproject { namespace lyphone。而在生成的Java代碼文件中將成為包名。 九、Options。 Protocol Buffer允許我們在.proto文件中定義一些常用的選項,這樣可以指示Protocol Buffer編譯器幫助我們生成更為匹配的目標語言代碼。Protocol Buffer內置的選項被分為以下三個級別: 1. 文件級別,這樣的選項將影響當前文件中定義的所有消息和枚舉。 2. 消息級別,這樣的選項僅影響某個消息及其包含的所有字段。 3. 字段級別,這樣的選項僅僅響應與其相關的字段。 下面將給出一些常用的Protocol Buffer選項。 1. option java_package = "com.companyname.projectname"; java_package是文件級別的選項,通過指定該選項可以讓生成Java代碼的包名為該選項值,如上例中的Java代碼包名為com.companyname.projectname。與此同時,生成的Java文件也將會自動存放到指定輸出目錄下的com/companyname/projectname子目錄中。如果沒有指定該選項,Java的包名則為package關鍵字指定的名稱。該選項對于生成C++代碼毫無影響。 2. option java_outer_classname = "LYPhoneMessage"; java_outer_classname是文件級別的選項,主要功能是顯示的指定生成Java代碼的外部類名稱。如果沒有指定該選項,Java代碼的外部類名稱為當前文件的文件名部分,同時還要將文件名轉換為駝峰格式,如:my_project.proto,那么該文件的默認外部類名稱將為MyProject。該選項對于生成C++代碼毫無影響。 注:主要是因為Java中要求同一個.java文件中只能包含一個Java外部類或外部接口,而C++則不存在此限制。因此在.proto文件中定義的消息均為指定外部類的內部類,這樣才能將這些消息生成到同一個Java文件中。在實際的使用中,為了避免總是輸入該外部類限定符,可以將該外部類靜態引入到當前Java文件中,如:import static com.company.project.LYPhoneMessage.*。 3. option optimize_for = LITE_RUNTIME; optimize_for是文件級別的選項,Protocol Buffer定義三種優化級別SPEED/CODE_SIZE/LITE_RUNTIME。缺省情況下是SPEED。 SPEED: 表示生成的代碼運行效率高,但是由此生成的代碼編譯后會占用更多的空間。 CODE_SIZE: 和SPEED恰恰相反,代碼運行效率較低,但是由此生成的代碼編譯后會占用更少的空間,通常用于資源有限的平臺,如Mobile。 LITE_RUNTIME: 生成的代碼執行效率高,同時生成代碼編譯后的所占用的空間也是非常少。這是以犧牲Protocol Buffer提供的反射功能為代價的。因此我們在C++中鏈接Protocol Buffer庫時僅需鏈接libprotobuf-lite,而非libprotobuf。在Java中僅需包含protobuf-java-2.4.1-lite.jar,而非protobuf-java-2.4.1.jar。 注:對于LITE_MESSAGE選項而言,其生成的代碼均將繼承自MessageLite,而非Message。 4. [pack= true]: 因為歷史原因,對于數值型的repeated字段,如int32、int64等,在編碼時并沒有得到很好的優化,然而在新近版本的Protocol Buffer中,可通過添加[pack=true]的字段選項,以通知Protocol Buffer在為該類型的消息對象編碼時更加高效。如: repeated int32 samples = 4 [packed=true]。 注:該選項僅適用于2.3.0以上的Protocol Buffer。 5. [default= default_value]: optional類型的字段,如果在序列化時沒有被設置,或者是老版本的消息中根本不存在該字段,那么在反序列化該類型的消息是,optional的字段將被賦予類型相關的缺省值,如bool被設置為false,int32被設置為0。Protocol Buffer也支持自定義的缺省值,如: optional int32 result_per_page = 3 [default = 10]。 十、命令行編譯工具。 protoc--proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR path/to/file.proto 這里將給出上述命令的參數解釋。 1. protoc為Protocol Buffer提供的命令行編譯工具。 2. --proto_path等同于-I選項,主要用于指定待編譯的.proto消息定義文件所在的目錄,該選項可以被同時指定多個。 3. --cpp_out選項表示生成C++代碼,--java_out表示生成Java代碼,--python_out則表示生成Python代碼,其后的目錄為生成后的代碼所存放的目錄。 4. path/to/file.proto表示待編譯的消息定義文件。 注:對于C++而言,通過Protocol Buffer編譯工具,可以將每個.proto文件生成出一對.h和.cc的C++代碼文件。生成后的文件可以直接加載到應用程序所在的工程項目中。如:MyMessage.proto生成的文件為MyMessage.pb.h和MyMessage.pb.cc。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕在线看视频国产欧美| 欧美中文在线视频| 精品国产老师黑色丝袜高跟鞋| 亚洲高清福利视频| 在线成人激情黄色| 亚洲va男人天堂| 97在线精品视频| 国产婷婷97碰碰久久人人蜜臀| 亚洲欧美在线免费观看| 成人黄色短视频在线观看| 国模精品系列视频| 亚洲天堂第一页| 亚洲精品一区在线观看香蕉| 一本色道久久88精品综合| 亚洲毛片在线观看| 国产欧美一区二区三区久久人妖| 久久国产精品首页| 亚洲成人网久久久| 亚洲四色影视在线观看| 97色在线视频观看| 亚洲日韩中文字幕在线播放| 中文字幕精品在线视频| 97精品国产97久久久久久免费| 最好看的2019的中文字幕视频| 国产97色在线| 精品国产一区二区在线| 欧美日韩亚洲一区二区| 中文字幕一区二区三区电影| 草民午夜欧美限制a级福利片| 国产欧美韩国高清| 精品国产一区久久久| 亚洲国产福利在线| 日韩视频在线观看免费| 久久久免费精品视频| 欧美视频免费在线| 琪琪第一精品导航| 久久久久久久久久av| 国产精品欧美日韩一区二区| 亚洲欧美日本精品| 日本精品一区二区三区在线播放视频| 81精品国产乱码久久久久久| 午夜剧场成人观在线视频免费观看| 一区二区三区 在线观看视| 51久久精品夜色国产麻豆| 国产成人在线亚洲欧美| 欧美性受xxx| 精品二区三区线观看| 亚洲一级免费视频| 九九热这里只有在线精品视| 国产人妖伪娘一区91| 亚洲精品av在线播放| 精品在线小视频| 欧美国产视频一区二区| 欧美精品少妇videofree| 成人激情综合网| 91影视免费在线观看| 国产精品一区久久久| 亚洲日本中文字幕免费在线不卡| 欧美中文字幕精品| 国产精品视频久久久| 91精品在线播放| 久久久久久美女| 日韩精品免费视频| 日韩毛片中文字幕| 91精品国产777在线观看| 色综合男人天堂| 日韩av片电影专区| 中文字幕综合一区| 日本欧美中文字幕| 精品美女久久久久久免费| 国产91精品最新在线播放| 亚洲国产欧美久久| 色老头一区二区三区| 亚洲va国产va天堂va久久| 欧美激情国产高清| 日韩电视剧在线观看免费网站| 欧美成人sm免费视频| 不卡av电影院| 88国产精品欧美一区二区三区| 免费av在线一区| 欧美在线观看网站| 亚洲性视频网站| 国产精品男女猛烈高潮激情| 裸体女人亚洲精品一区| 亚洲综合在线做性| 亚洲久久久久久久久久久| 国产成人精品免高潮费视频| 日韩高清中文字幕| 亚洲欧美激情精品一区二区| 岛国av一区二区在线在线观看| 午夜伦理精品一区| 久久久精品中文字幕| 日韩毛片中文字幕| 中文字幕综合一区| 国产精品久久视频| 深夜福利亚洲导航| 日韩av网站电影| 日韩在线激情视频| 欧美巨猛xxxx猛交黑人97人| 日韩高清电影免费观看完整| 91亚洲一区精品| 国产欧美精品在线播放| 精品少妇一区二区30p| 亚洲精品v天堂中文字幕| 成人黄色av免费在线观看| 欧美激情国产日韩精品一区18| 亚洲自拍偷拍区| 久久精品这里热有精品| 日韩中文字幕精品视频| 日本精品久久久久影院| 国产一区二区三区免费视频| 日韩av在线影院| 在线免费观看羞羞视频一区二区| 欧美激情一二三| 欧美猛交ⅹxxx乱大交视频| 日韩精品视频免费| 欧美老女人在线视频| 亚洲wwwav| www.日本久久久久com.| 一区二区三区日韩在线| 亚洲色无码播放| 国产欧美日韩精品丝袜高跟鞋| 亚洲高清一二三区| 色香阁99久久精品久久久| 亚洲性生活视频在线观看| 亚洲成人动漫在线播放| 国产精品高精视频免费| 国产精品流白浆视频| 尤物九九久久国产精品的特点| 久久偷看各类女兵18女厕嘘嘘| 国产精品美女视频网站| 97免费在线视频| 亚洲福利精品在线| 欧美激情在线播放| 国产精品欧美一区二区三区奶水| 精品香蕉在线观看视频一| 国产+成+人+亚洲欧洲| 日本久久91av| 久久精品99久久香蕉国产色戒| 欧美日韩精品在线视频| 亚洲福利视频专区| 国产成人精品久久久| 日韩美女在线观看一区| 国产91精品视频在线观看| 欧美黑人性生活视频| 国产在线精品一区免费香蕉| 粗暴蹂躏中文一区二区三区| 超碰97人人做人人爱少妇| 久久国内精品一国内精品| 亚洲欧美精品伊人久久| 性金发美女69hd大尺寸| 亚洲欧洲偷拍精品| 欧美日韩国产区| xxx成人少妇69| 久久久影视精品| 亚洲天堂免费视频| 欧美激情一区二区三区高清视频| 亚洲毛片在线看| 北条麻妃一区二区三区中文字幕| 国产精品jizz在线观看麻豆| 国产成人福利夜色影视| 成人黄色片网站| 亚洲风情亚aⅴ在线发布| 91高清视频在线免费观看|