1. 程式人生 > >google protobuf學習筆記二:使用和原理

google protobuf學習筆記二:使用和原理

一.什麼是protobuf

protobuf全稱Google Protocol Buffers,是google開發的的一套用於資料儲存,網路通訊時用於協議編解碼的工具庫。它和XML或者JSON差不多,也就是把某種資料結構的資訊,以某種格式(XML,JSON)儲存起來,protobuf與XML和JSON不同在於,protobuf是基於二進位制的。主要用於資料儲存、傳輸協議格式等場合。那既然有了XML等工具,為什麼還要開發protobuf呢?主要是因為效能,包括時間開銷和空間開銷:

1.時間開銷:XML格式化(序列化)和XML解析(反序列化)的時間開銷是很大的,在很多時間效能上要求很高的場合,你能做的就是看著XML乾瞪眼了。

2.空間開銷:熟悉XML語法的同學應該知道,XML格式為了有較好的可讀性,引入了一些冗餘的文字資訊。所以空間開銷也不是太好(應該說是很差,通常需要實際內容好幾倍的空間)。

據實驗(當然不是我實驗),一條訊息資料,用protobuf序列化後的大小是json格式的十分之一,xml格式的二十分之一。

這一篇主要講protobuf用作資料儲存方面,下一篇講用作rpc通訊協議方面。

二.使用protobuf

protobuf的使用很簡單,開發人員按照一定的語法定義結構化的訊息格式,然後用自帶的編譯工具,工具將自動生成相關的類,官方支援java、c++、python語言環境(當然可以在網上找到很多支援其他語言的封裝,當然你也可以自己寫一個,只要符合google定義的格式)。通過將這些類包含在專案中,可以很輕鬆的呼叫相關方法來完成業務訊息的序列化與反序列化工作。


1.定義報文格式。protobuf檔案的字尾是proto,是一種類似c++或者java的語法。使用protoc.exe(windows平臺下,你可以下載原始碼編譯,也可以網上直接下載exe,這個大家自行Google)把proto檔案編譯成c++,java或者Python就可以使用了。

package tutorial;

message Person {
  required string name = 1;
  required int32 age = 2;
  optional string email = 3;

}

在這裡定義了一個Person,我們只是簡單的定義了name,age和email。這裡注意,在上例中,package 名字叫做 tutorial,相當於c++的namespace,定義了一個訊息 Person,該訊息有3個成員,型別為 string 的 name,型別為 int32 的成員 age和型別為string的email。optional 代表這是一個可選的成員,即訊息中可以不包含該成員,required代表是必須的。

寫好proto之後把proto放在protoc.exe相同目錄,然後在此目錄使用指令:protoc --cpp_out=d:\proto person.proto(我們使用的是c++)。當用protocolbuffer編譯器來執行.proto檔案時,編譯器將生成所選擇語言的程式碼,這些程式碼可以操作在.proto檔案中定義的訊息型別,包括獲取、設定欄位值,將訊息序列化到一個輸出流中,以及從一個輸入流中解析訊息。

就可以生成person.pb.h,person.pb.cc.在生成的標頭檔案中,定義了一個 C++ 類 Person,繼承自google::protobuf::Message,後面我們進行對Person資料的檔案讀寫, 將使用這個類來對訊息進行操作。諸如對訊息的成員進行賦值,將訊息序列化等等都有相應的方法。

首先,把資料寫入disk:

#include <iostream>
#include<fstream>
#include "person.pb.h"

#pragma comment(lib, "libprotobuf.lib")
#pragma comment(lib, "libprotoc.lib")

using namespace std;
using namespace tutorial;

int main()
{
	Person person;

	person.set_name("flamingo");   
	person.set_age(18); 
	person.set_email("[email protected]");

	// Write
	fstream output("./log", ios::out | ios::trunc | ios::binary);

	if (!person.SerializeToOstream(&output)) {
		cerr << "Failed to write msg." << endl;
		return -1;
	}

	system("pause");
	return 0;
}

namespace tutorial就是我們之前定義的package,我們先定義一個Person,然後給Person賦值,其中set_name,set_age,set_email是根據proto自動生成的,我們使用SerializeToOstream 將物件序列化成二進位制(導致了可讀性差的問題,這算是protobuf的一個缺點吧)後寫入一個 fstream 流。

然後在從disk讀出Person的資料:

#include <iostream>
#include<fstream>
#include "person.pb.h"

#pragma comment(lib, "libprotobuf.lib")
#pragma comment(lib, "libprotoc.lib")

using namespace std;
using namespace tutorial;

void PrintInfo(const Person & person) { 
	cout << person.name() << endl; 
	cout << person.age() << endl; 
	cout << person.email() << endl;
} 

int main()
{
	Person person;  

	fstream input("./log", ios::in | ios::binary);
	
	if (!person.ParseFromIstream(&input)) {
		cerr << "Failed to parse address book." << endl;
		return -1;
	}

	PrintInfo(person);

	system("pause");
	return 0;
}


主要是利用 ParseFromIstream 從一個 fstream 流中讀取序列化的資訊並反序列化。


下一篇將講利用protobuf rpc進行資料傳輸。

相關推薦

google protobuf學習筆記使用原理

一.什麼是protobuf protobuf全稱Google Protocol Buffers,是google開發的的一套用於資料儲存,網路通訊時用於協議編解碼的工具庫。它和XML或者JSON差不多,也就是把某種資料結構的資訊,以某種格式(XML,JSON)儲存起來

Django學習筆記實現部落格詳情,完善文章的分類標籤

前面我已經學會了使用Django框架搭建一個簡單的部落格框架。接下來學習的就是如何完善部落格的功能。 部落格詳情 功能 當用戶點選文章的“繼續閱讀”按鈕時,實現瀏覽文章的具體內容。即當點選“繼續閱讀”時根據傳入的請求和文章的id引數跳轉到對應的

Caffe學習筆記()使用Python生成caffe所需的lmdb檔案txt列表清單檔案

轉載請註明作者和出處: http://blog.csdn.net/c406495762 Python版本:Python2.7 執行平臺:Ubuntu14.04 最後修改時間:2017.4.20     在上個筆記中,已經學會了如何使用Caffe利用作者

nodejs學習筆記閉包非同步程式設計

閉包到底是什麼鬼 閉包就是函式��,但是它可以繼承並訪問它自身被宣告的那個作用域裡的變數。當你將一個回撥函式作為引數傳遞給另外一個進行i/o操作的函式時,回撥函式稍後會被呼叫,神奇的是,在被呼叫時,回撥函式會記住它自身宣告時所在的上下文,並且可以訪問該上下文及

Guava學習筆記()Google Guava (瓜娃)的API快速熟悉使用

1,大綱 讓我們來熟悉瓜娃,並體驗下它的一些API,分成如下幾個部分: IntroductionGuava Collection APIGuava Basic UtilitiesIO APICache API 2,為神馬選擇瓜娃? 瓜娃是java API蛋糕上的冰

zTree學習筆記展開樹收起樹

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <ti

matlab學習筆記plot畫圖怎麼設定線條型別顏色

matlab的繪圖功能很強大,因此它在科學實驗和社會調研中被廣泛應用。我們在繪製圖形時怎麼選擇線條的型別?比如需要虛線,星點線。。。或者怎麼設定線條的顏色?下面將將進行介紹。下面將以一個簡單的繪圖操作為例。繪製0到2*pi範圍內的正弦餘弦函式,預設的圖形是實線,顏色第一條是藍

SpringMVC學習筆記常用註解

title c學習 請求 pin 學習 lin att 詳解 stp 轉載請註明原文地址:http://www.cnblogs.com/ygj0930/p/6831976.html 一、用於定義類的註解:@Controller @Controller 用於標記在一個類上,

framework7學習筆記基礎知識

部分 cnblogs query 基礎 logs code 自己 $$ pan 一:DOM7 framework7有自己的 DOM7 - 一個集成了大部分常用DOM操作的高性能庫。它的用法和jQuery幾乎是一樣的,包括大部分常用的方法和jquery風格的鏈式調用。 在開發

Spring4學習筆記Bean相關

因此 code per cdata 通過 反射機制 特殊符號 cat too 一:Bean的配置形式 基於XML配置:在src目錄下創建 applicationContext.xml 文件,在其中進行配置。 基於註解配置:在創建bean類時,通過註解來

小程序學習筆記頁面文件詳解之 .json文件

fresh 小程序 整體 屬性 spa hit rbac style mdi 頁面配置文件—— pageName.json 每一個小程序頁面可以使用.json文件來對本頁面的窗口表現進行配置,頁面中配置項會覆蓋 app.json 的 window 中相同的配置

Docker學習筆記Docker的安裝

ros -h bionic docker customer tex 鏈接 space 版本 安裝環境:操作系統:Ubuntu 18.04 LTS,code name:bionic (#lsb_release -a)內核版本:4.15.0-29-generic(#uname

基於.NET的CAD次開發學習筆記AutoCAD .NET中的物件

1、CAD物件 一個CAD檔案(DWG檔案)即對應一個數據庫,資料庫中的所有組成部分,看的見(包括點、多段線、文字、圓等)和看不見(圖層、線型、顏色等)的都是物件,資料庫本身也是一個物件。 直線、圓弧、文字和標註等圖形物件都是物件。 線型與標註樣式等樣式設定都是物件。 圖層

分散式學習筆記從分散式一致性談到CAP理論、BASE理論

問題的提出 在電腦科學領域,分散式一致性是一個相當重要且被廣泛探索與論證問題,首先來看三種業務場景。 1、火車站售票 假如說我們的終端使用者是一位經常坐火車的旅行家,通常他是去車站的售票處購買車 票,然後拿著車票去檢票口,再坐上火車,開始一段美好的旅行----一切似乎都是那麼和諧。想象一

C++學習筆記 () ---- 類物件

①、類和物件 類的定義,如下: class Student{ public: //成員變數 char *name; int age; float score; //成員函式 void say(){ cout<<

轉載InstallShield學習筆記元件配置

InstallShield學習筆記二:元件配置 這裡主要講的記錄的是配置檔案的細節。 1.Features配置 在 Installshield 中,可以在 Features 新增需要安裝元件大類,這裡需要注意的是: 在InstallSrcipt MSI ,預設DefaultFeatu

JavaScript 學習筆記基本知識

文章目錄 預備知識 JavaScript web 開發人員必須學習的 3 門語言中的一門: 如何編寫JavaScript? 如何執行JavaScript 使用 JavaScript的兩種方式 1. 指令碼是直

csdn學習筆記連結串列原型、do原型分析

設計連結串列,並設計其迭代函式 生成連結串列、列印連結串列 arr = {10, 20, 30, 100, 101, 88, 50}; head = nil; local i = 1 while true do if arr[i] then head = {va

python學習筆記列表

列表通過索引讀取資料: #索引讀取資料 a = [1,2,3] a[-1] 執行結果:3 列表支援巢狀: b = [[1,2,3],[4,5,6]] print(b) 執行結果:[[1, 2, 3], [4, 5, 6]] 列表可以修改: b = [[1,2,3],[4,5,

mapreduce學習筆記去重實驗

bound pac except 計算 throws 問題 多少 tasks tostring 實驗原理 “數據去重”主要是為了掌握和利用並行化思想來對數據進行有意義的篩選。統計大數據集上的數據種類個數、從網站日誌中計算訪問地等這些看似龐雜的任務都