protocol buffers使用說明

一、什么是protocol buffers

Protocol buffers是一個靈活的、高效的、自動化的用于對結構化數據進行序列化的協議,與XML相比,Protocol buffers序列化后的碼流更小、速度更快、操作更簡單。你只需要將要被序列化的數據結構定義一次(譯注:使用.proto文件定義),便可以使用特別生成的源代碼(譯注:使用protobuf提供的生成工具)輕松的使用不同的數據流完成對這些結構數據的讀寫操作,即使你使用不同的語言(譯注:protobuf的跨語言支持特性)。你甚至可以更新你的數據結構的定義(譯注:就是更新.proto文件內容)而不會破壞依賴“老”格式編譯出來的程序。

二、protocol buffers的工作流程

首先,你需要通過在.proto文件中定義protocol buffer的message類型來指定你想要序列化的數據結構,每一個protocol buffer message是一個邏輯上的信息記錄,它包含一系列的鍵值對。這里展示一個最基本的.ptoto文件的例子,它定義了一個包含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;
}

正如你所看見的那樣,message的格式非常簡單–每一個message類型都有一個或多個帶有唯一編號的字段,每一個字段有一個字段名和一個字段類型,字段類型可以是數值類型(比如整形或浮點型)、booleans(布爾類型)、strings(字符串類型)、raw bytes、甚至(正如上面的例子)還可以是其他的protocol buffer message類型,這允許你可以分層次的組織你的數據結構。你可以單獨指定每一個字段為optional fields(可選字段)、required fields(必須字段)、repeated fields(可重復字段)。下一篇博文將會對.proto文件進行更詳細的描述。

一旦定義了你的message,你就可以根據你所使用的語言(譯注:如JAVA、C++、Python等)使用protocol buffer提供的編譯工具編譯.proto文件生成數據訪問類。這些類為每一個字段都提供了簡單的訪問器(比如name()和set_name()),同時還提供了將整個結構化數據序列化為原始字節數據以及從原始字節數據反序列化為結構化數據的方法(譯注:C++中稱之為函數)。例如,如果你使用的語言是C++,運行編譯器編譯上述的例子將生成一個名為Person的類,在你的應用程序中你可以使用這個類來填充、序列化和反序列化Person protocol buffer messages。之后你可能會寫下如下類似的代碼(譯注:序列化):

Person person;
person.set_name("John Doe");
person.set_id(1234);
person.set_email("jdoe@example.com");
fstream output("myfile", ios::out | ios::binary);
person.SerializeToOstream(&output);

之后,你可以將你的message讀回(譯注:反序列化):

fstream input("myfile", ios::in | ios::binary);
Person person;
person.ParseFromIstream(&input);
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;

你可以向你的message中添加新的字段而不會破壞前向兼容性;在解析時舊的二進制文件會簡單的忽略掉新字段,所以,如果你的通信協議中使用protocol buffers作為數據交換格式,那么你可以擴展你的協議而不用擔心會打亂現有的代碼。

三、為什么不使用XML?

相對于XML,protocol buffers在序列化結構數據時擁有許多先進的特性:

1、更簡單

2、序列化后字節占用空間比XML少3-10倍

3、序列化的時間效率比XML快20-100倍

4、具有更少的歧義性

5、自動生成數據訪問類方便應用程序的使用

舉個例子,如果你想描述一個具有name和email的person數據結構,在XML中,你需要這樣做:

<person><name>John Doe</name><email>jdoe@example.com</email></person>

然而,在protocol buffers的message中(protocol buffers的文本格式)你需要這樣做:

# Textual representation of a protocol buffer.
# This is *not* the binary format used on the wire.
person {name: "John Doe"email: "jdoe@example.com"
}

當這個message被編碼成protocol buffer的二進制格式(上述的文本格式只是為了方便閱讀、調試和編輯),它將可能占用28個字節長度并且僅需要100-200納秒的解析時間。相比,XML版本的則至少需要占用69字節的空間(這是在移除XML中的空格、換行之后),同時,將耗費大約5000-10000納秒的解析時間。

除此之外,手動操作protocol buffer更為方便,例如如下C++代碼:

cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;

然而如果你使用XML,那么你將需要這樣做:

cout << "Name: "<< person.getElementsByTagName("name")->item(0)->innerText()<< endl;
cout << "E-mail: "<< person.getElementsByTagName("email")->item(0)->innerText()<< endl;

事物總有兩面性,和XML相比protocol buffers并不總是更好的選擇,例如,protocol buffers并不適合用來描述一個基于文本的標記型文檔(比如HTML),因為你無法輕易的交錯文本的結構。另外,XML具有很好的可讀性和可編輯性;而protocol buffers,至少在它們的原生形式上并不具備這個特點。XML同時也是可擴展、自描述的。而一個protocol buffer只有在具有message 定義(在.proto文件中定義)時才會有意義。

四、如何開始使用protocol buffers?

首先,可以在這里下載安裝包或者源碼包

https://developers.google.com/protocol-buffers/docs/downloads#release-packages

這包含了針對JAVA、Python和C++編譯器的完整源碼,同時包含了你所需要的I/O和測試類。為了完成編譯和安裝,請參照README文件。

一旦你完成了編譯和安裝,那么就可以開始使用protocol buffers了,后續的博文將會對C++和JAVA語言的具體使用細節進行闡述。

五、proto3介紹

我們最新的版本version 3 alpha release引進了一個新的語言版本–Protocol Buffers version 3 (稱之為proto3),它在我們現存的語言版本(proto2)上引進了一些新特性。proto3簡化了protocol buffer language,這使其可以更便于使用和支持更多的編程語言:我們現在的alpha release版本可以讓你能產生JAVA、C++、Pthyon、JavaNano、Ruby、Objective-C和C#版本的protocol buffer code,不過可能有時會有一些局限性。另外,你可以使用最新的Go protoc插件來產生Go語言版本的proto3 code,這可以從golang/protobuf Github repository獲取。

我們現在只推薦你使用proto3:

1、如果你想嘗試在我們新支持的語言中使用protocol buffers

2、如果你想嘗試我們最新開源的RPC實現gRPC(目前仍處于alpha release版本),我們建議你為所有的gRPC 服務器和客戶端都使用proto3以避免兼容性問題。

注意兩個版本的語言APIs并不是完全兼容的,為了避免給原來的用戶造成不便,我們將會繼續維護之前的那個版本(譯注:proto2)。

六、最后說一點歷史

Protocol buffers最初被Google開發用來作為處理索引服務器的request/response協議。在protocol buffers誕生之前,有一個需要手動編碼/解碼requests、responses的協議,這個協議支持一個數字版本號,這導致了一個非常丑陋的代碼,如下所示:

if (version == 3) {...} else if (version > 4) {if (version == 5) {...}...}

很顯然的,格式化的協議也導致了復雜的新版本推出問題,因為開發人員必須確保所有服務器請求的發起者和實際的請求處理者之間都要理解新的協議。

Protocol buffers就是用來解決這些問題的:

1、可以很容易的插入新字段,中間的服務器可以簡單的解析它而不需要了解所有字段。

2、格式更具有自描述性,可以被不同的語言處理(比如JAVA、C++、Python等)。

3、自動產生序列化和反序列化代碼從而避免了手動解析。

4、除了應用在具有短暫生命周期的RPC請求中,人們開始使用protocol buffers 作為一種便利的自描述格式來存儲數據(比如在Bigtable中)。

5、服務器的RPC接口開始被聲明為協議文件的一部分,通過protocol 編譯器產生stub類,該類可以被用戶根據實際實現的服務器接口進行重寫。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448225.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448225.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448225.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

jeeCMS首頁加載流程

版權聲明&#xff1a;本文為博主原創文章&#xff0c;未經博主允許不得轉載。 https://blog.csdn.net/gyshun/article/details/79669293 如果JEECMS部署完畢之后&#xff0c;在瀏覽器中輸入http://localhost:8080/jeecms&#xff0c;系統直接會按照以下步驟執行&#xff1a; 首…

車子突然溜坡追尾 駕校教練說掛P擋拉手剎不會溜坡

昨天4:44&#xff0c;朱先生來電&#xff1a;剛才登云路一個燒烤店門口&#xff0c;一輛車停在自己的車位上的&#xff0c;不知什么原因&#xff0c;突然溜坡撞上前面的一輛出租車。稀奇的是&#xff0c;這個溜坡的駕駛員全程都是車上睡覺睡著的&#xff0c;什么都不知道。記者…

VSCode 漢化、設置為 中文語言顯示 、中文界面

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Vscode是一款開源的跨平臺編輯器。默認情況下&#xff0c;vscode使用的語言為英文(us)&#xff0c;如何將其顯示語言修改成中文了&#…

c++執行vbs腳本

#include<fstream> using namespace std;int main() {fstream out("StartIE.vbs",ios::out);out<<"AppName\"啟動IE\"\n\Set WshellWScript.CreateObject(\"WScript.Shell\")\n\Set ieWScript.CreateObject(\"InternetEx…

Python-21-socket編程

一、基礎知識 1. C/S架構 C/S架構即客戶機/服務器模式。 它可以分為客戶機和服務器兩層&#xff1a; 第一層: 在客戶機系統上結合了界面顯示與業務邏輯&#xff1b; 第二層: 通過網絡結合了數據庫服務器。 簡單的說就是第一層是用戶表示層&#xff0c;第二層是數據庫層。 這里…

解決:VScode 漢化后 、設置中文后 還顯示英文的問題

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 按f1 搜索 Configore Display Language 設置 zh-cn 關閉軟件重啟。 如果重啟菜單等還是英文的&#xff0c;在商店查看已安裝的插件&…

自動擋怎么開-自動擋汽車怎么開?

汽車改用自動變速器后&#xff0c;駕駛員的操作更加簡便、駕駛更加平順&#xff0c;因此裝備自動變速器的新型轎車尤其受到了人們的青睞。不過&#xff0c;很多駕駛者初開自動擋車時&#xff0c;由于對自動變速器的結構和原理不是很了解&#xff0c;行車時經常是一個D擋走完全程…

CreateThread函數

創建一個在調用進程的虛擬地址空間內執行的線程。 要創建在另一個進程的虛擬地址空間中運行的線程&#xff0c;請使用 CreateRemoteThread函數。 語法 HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START…

nginx 的請求處理、請求的處理流程

nginx的請求處理 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 nginx使用一個多進程模型來對外提供服務&#xff0c;其中一個master進程&#xff0c;多個worker進程。master進程負責…

如何控制油門更準確?

學員問&#xff1a;平時練車還不錯&#xff0c;可是一換車就容易加大油門&#xff0c;有什么方法能很好的控制油呢&#xff1f;&#xff1f; 如何控制油門更準確&#xff1f;和調的座位有關系嗎&#xff1f;&#xff1f; 答&#xff1a;油門跟剎車被視為汽車控制的靈魂。汽車發…

使用線程——創建線程

CreateThread函數創建一個進程的新的線程。創建線程必須指定新線程要執行的代碼的起始地址。通常&#xff0c;起始地址是程序代碼中定義的函數的名稱&#xff08;有關更多信息&#xff0c;請參閱ThreadProc&#xff09;。此函數采用單個參數并返回DWORD值。一個進程可以讓多個線…

location

location (地址)&#xff1a; 是瀏覽器 window 上的一個對象&#xff0c;不僅能處理當前頁面的網絡地址&#xff0c;還可以實現頁面間的跳轉 頁面的跳轉&#xff1a; 為什么使用它&#xff1f; 使我們也可以通過腳本語言&#xff0c;也能實現 a 鏈接&#xff0c;同樣的效果&…

linux :Docker 方式 安裝 zookeeper、阿里服務器上 Docker 運行 zookeeper

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 查找官方鏡像&#xff0c;并下載鏡像&#xff1a; # 搜索鏡像&#xff1a; docker search zookeeper# 拉取鏡像&#xff1a;docker …

使用線程池功能

此示例創建自定義線程池&#xff0c;創建工作項和線程池計時器&#xff0c;并將它們與清理組關聯。該池由一個持久性線程組成。它演示了以下線程池函數的使用&#xff1a; CloseThreadpool CloseThreadpoolCleanupGroupCloseThreadpoolCleanupGroupMembersCloseThreadpoolWait…

制動剎車片六個養護要點

剎車片屬于消耗品&#xff0c;在使用中會逐漸磨損&#xff0c;當磨損到極限位置時&#xff0c;必須更換&#xff0c;否則將降低制動的效果&#xff0c;甚至造成安全事故。 制動剎車片關乎生命安全&#xff0c;必須謹慎對待。 大多數轎車采用前盤后鼓式制動器結構&#xff0c;一…

Learn day4 函數參數\變量\閉包\遞歸

1.函數描述 # ### 函數 """ (1)函數的定義:功能 (包裹一部分代碼 實現某一個功能 達成某一個目的) (2)函數特點:可以反復調用,提高代碼的復用性,提高開發效率,便于維護管理 """# (3) 函數的基本格式 """ # 函數的定義處 def fun…

Java 中去除字符串中空格的方法

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1、方法分類 str.trim(); //去掉首尾空格str.replace(" ",""); //去除所有空格&#xff0c;包括首尾、中間str.re…

使用重定向的輸入和輸出創建子進程

本主題中的示例演示如何使用控制臺進程中的CreateProcess函數創建子進程。它還演示了一種使用匿名管道重定向子進程的標準輸入和輸出句柄的技術。請注意&#xff0c;命名管道也可用于重定向進程I / O. 所述CreatePipe函數使用SECURITY_ATTRIBUTES結構來創建可繼承句柄讀寫兩個…

手動擋停車時掛檔有技巧

徐小姐來電&#xff1a;我家的汽車要年檢了&#xff0c;前幾天&#xff0c;工作人員幫我把車子開進檢測站去檢測&#xff0c;開回來后停在原位上&#xff0c;然后把鑰匙交給我。我拿鑰匙一點火&#xff0c;車子就突然往前動了&#xff0c;根本沒有時間反應&#xff0c;已經撞到…

LOJ 3156: 「NOI2019」回家路線

題目傳送門&#xff1a;LOJ #3156。 題意簡述&#xff1a; 有一張 \(n\) 個點 \(m\) 條邊的有向圖&#xff0c;邊有兩個權值 \(p_i\) 和 \(q_i\)&#xff08;\(p_i<q_i\)&#xff09;表示若 \(p_i\) 時刻在這條邊的起點&#xff0c;則 \(q_i\) 時刻能到達這條邊的終點。 你需…