最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

protobuf簡介及使用流程

 更新時間:2025年02月26日 14:13:44   作者:不如小布.  
本文介紹了Protocol Buffers(protobuf)的數(shù)據(jù)結構序列化和反序列化框架,包括其特點、使用流程和快速上手,通過一個簡單的通訊錄示例,展示了如何創(chuàng)建.proto文件、添加注釋、編寫消息定義、編譯.proto文件以及進行序列化和反序列化操作,感興趣的朋友一起看看吧

1. Protobuf是什么

  ProtoBuf(全稱Protocol Buffer)是數(shù)據(jù)結構序列化和反序列化框架,它具有以下特點:

  • 語??關、平臺無關:即 ProtoBuf ?持 Java、C++、Python 等多種語?,?持多個平臺
  • ?效:即? XML 更小、更快、更為簡單
  • 擴展性、兼容性好:你可以更新數(shù)據(jù)結構,而不影響和破壞原有的舊程序

2. Protobuf使?流程介紹

  • 編寫 .proto ?件,?的是為了定義結構對象(message)及屬性內(nèi)容。
  • 使? protoc 編譯器編譯 .proto ?件,?成?系列接?代碼,存放在新?成頭?件和源?件中。
  • 依賴?成的接?,將編譯?成的頭?件包含進我們的代碼中,實現(xiàn)對 .proto ?件中定義的字段進行設置和獲取,和對 message 對象進行序列化和反序列化

3. ProtoBuf快速上手

  我們以?個簡單通訊錄的實現(xiàn)來驅動對Protobuf的學習。在通訊錄demo中,我們將實現(xiàn):

  • 對?個聯(lián)系?的信息使? Protobuf 進?序列化,并將結果打印出來。
  • 對序列化后的內(nèi)容使? Protobuf 進?反序列,解析出聯(lián)系?信息并打印出來。
  • 聯(lián)系?包含以下信息: 姓名、年齡。

  通過通訊錄demo,我們能快速的了解ProtoBuf的使?流程。

3.1 創(chuàng)建 .proto ?件

  • 創(chuàng)建 .proto ?件時,?件命名應該使?全?寫字?命名,多個字?之間? _ 連接。 例如:lower_snake_case.proto
  • 書寫 .proto ?件代碼時,應使? 2 個空格的縮進。

  我們?yōu)橥ㄓ嶄?demo 新建?件: contacts.proto

3.2 添加注釋

  向?件添加注釋,可使? // 或者 /* … */

3.3 具體編寫

  指定 proto3 語法:
  Protocol Buffers 語?版本3,簡稱 proto3,是 .proto ?件最新的語法版本。proto3 簡化了 ProtocolBuffers 語?,既易于使?,?可以在更?泛的編程語?中使?。它允許你使? Java,C++,Python等多種語??成 protocol buffer 代碼。在 .proto ?件中,要使? syntax = “proto3”; 來指定?件語法為 proto3,并且必須寫在除去注釋內(nèi)容的第??。 如果沒有指定,編譯器會使?proto2語法。
  在通訊錄 demo 的 contacts.proto ?件中,可以為?件指定 proto3 語法,內(nèi)容如下:

syntax = "proto3";

   package 聲明符:
   package 是?個可選的聲明符,能表? .proto ?件的命名空間,在項?中要有唯?性。它的作?是為了避免我們定義的消息出現(xiàn)沖突。
   在通訊錄 demo 的 contacts.proto ?件中,可以聲明其命名空間,內(nèi)容如下:

package contacts;

   定義消息(message):
  消息(message): 要定義的結構化對象,我們可以給這個結構化對象中定義其對應的屬性內(nèi)容。在網(wǎng)絡傳輸中,我們需要為傳輸雙?定制協(xié)議。定制協(xié)議說?了就是定義結構體或者結構化數(shù)據(jù),?如,tcp,udp 報?就是結構化的。再?如將數(shù)據(jù)持久化存儲到數(shù)據(jù)庫時,會將?系列元數(shù)據(jù)統(tǒng)??對象組織起來,再進?存儲。ProtoBuf 就是以 message 的方式來?持我們定制協(xié)議字段,后期幫助我們形成類和?法來使用。
  在通訊錄 demo 中我們就需要為聯(lián)系人定義?個 message:

.proto ?件中定義?個消息類型的格式為:

message 消息類型名{
}
消息類型命名規(guī)范:使?駝峰命名法,?字??寫。

為 contacts.proto(通訊錄 demo)新增聯(lián)系?message

syntax = "proto3";
package contacts;
// 定義聯(lián)系?消息
message PeopleInfo {
}

  定義消息字段:
  在 message 中我們可以定義其屬性字段,字段定義格式為:字段類型 字段名 = 字段唯?編號;

  • 字段名稱命名規(guī)范:全?寫字?,多個字?之間? _ 連接。
  • 字段類型分為:標量數(shù)據(jù)類型 和 特殊類型(包括枚舉、其他消息類型等)。
  • 字段唯?編號:?來標識字段,?旦開始使?就不能夠再改變。

  樣例:

// 聲明語法版本
syntax = "proto3";
// 聲明代碼的命名空間
package contacts;
//結構化對象的描述
message PeopleInfo{
    // 各個字段描述:   字段類型  字段名 = 字段唯一編號
    string name = 1;
    int32 age = 2;
}

  注:這?還要特別講解?下字段唯?編號的范圍:1 ~ 536,870,911 (2^29 - 1) ,其中 19000 ~ 19999 不可?。
  19000 ~ 19999 不可?是因為:在 Protobuf 協(xié)議的實現(xiàn)中,對這些數(shù)進?了預留。如果?要在.proto?件中使?這些預留標識號,例如將 name 字段的編號設置為19000,編譯時就會報警。
  值得?提的是,范圍為 1 ~ 15 的字段編號需要?個字節(jié)進?編碼, 16 ~ 2047 內(nèi)的數(shù)字需要兩個字節(jié)進?編碼。編碼后的字節(jié)不僅只包含了編號,還包含了字段類型。所以 1 ~ 15 要?來標記出現(xiàn)?常頻繁的字段,要為將來有可能添加的、頻繁出現(xiàn)的字段預留?些出來。

3.4 編譯 contacts.proto 文件

  編譯命令?格式為:

protoc [--proto_path=IMPORT_PATH] --cpp_out=DST_DIR path/to/file.proto
protoc             是 Protocol Buffer 提供的命令?編譯?具。
--proto_path       指定被編譯的.proto?件所在?錄,可多次指定??珊唽懗?-I IMPORT_PATH 。如不指
                   定該參數(shù),則在當前?錄進?搜索。當某個.proto ?件 import 其他.proto ?件時,
                   或需要編譯的 .proto ?件不在當前?錄下,這時就要?-I來指定搜索?錄。
--cpp_out=         指編譯后的?件為 C++ ?件。
OUT_DIR            編譯后?成?件的?標路徑。
path/to/file.proto 要編譯的.proto?件

  編譯 contacts.proto ?件命令如下:

protoc --cpp_out=. contacts.proto

  編譯 contacts.proto ?件后,會?成所選擇語?的代碼,我們選擇的是C++,所以編譯后?成了兩個文件: contacts.pb.h contacts.pb.cc 。
  對于編譯?成的 C++ 代碼,包含了以下內(nèi)容 :

  • 對于每個 message ,都會?成?個對應的消息類
  • 在消息類中,編譯器為每個字段提供了獲取和設置?法,以及?下其他能夠操作字段的方法
  • 編輯器會針對于每個 .proto ?件?成 .h 和 .cc ?件,分別?來存放類的聲明與類的實現(xiàn)

  contacts.pb.h 部分代碼展示:

class PeopleInfo final : public ::PROTOBUF_NAMESPACE_ID::Message {
public:
	 using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
	 void CopyFrom(const PeopleInfo& from);
	 using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
	 void MergeFrom( const PeopleInfo& from) {
	 PeopleInfo::MergeImpl(*this, from);
 }
 static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
	 return "PeopleInfo";
 }
	 // string name = 1;
	 void clear_name();
	 const std::string& name() const;
	 template <typename ArgT0 = const std::string&, typename... ArgT>
	 void set_name(ArgT0&& arg0, ArgT... args);
	 std::string* mutable_name();
	 PROTOBUF_NODISCARD std::string* release_name();
	 void set_allocated_name(std::string* name);
	 // int32 age = 2;
	 void clear_age();
	 int32_t age() const;
	 void set_age(int32_t value);
};

  上述的例?中:

  • 每個字段都有設置和獲取的方法, getter 的名稱與?寫字段完全相同,setter ?法以 set_ 開頭。
  • 每個字段都有?個 clear_ 方法,可以將字段重新設置回 empty 狀態(tài)。

  contacts.pb.cc 中的代碼就是對類聲明?法的?些實現(xiàn),在這?就不展開了。
  到這?有人可能就有疑惑了,那之前提到的序列化和反序列化?法在哪?呢?在消息類的?類MessageLite 中,提供了讀寫消息實例的方法,包括序列化?法和反序列化?法。

class MessageLite {
public:
	//序列化:
	bool SerializeToOstream(ostream* output) const; // 將序列化后數(shù)據(jù)寫??件
	流
	bool SerializeToArray(void *data, int size) const;
	bool SerializeToString(string* output) const;
	//反序列化:
	bool ParseFromIstream(istream* input); // 從流中讀取數(shù)據(jù),再進?反序列化
	動作
	bool ParseFromArray(const void* data, int size);
	bool ParseFromString(const string& data);
};

  注意:

  • 序列化的結果為?進制字節(jié)序列,???本格式。
  • 以上三種序列化的?法沒有本質上的區(qū)別,只是序列化后輸出的格式不同,可以供不同的應?場景使?。
  • 序列化的 API 函數(shù)均為const成員函數(shù),因為序列化不會改變類對象的內(nèi)容, ?是將序列化的結果保存到函數(shù)?參指定的地址中

  序列化與反序列化的使用:
  創(chuàng)建?個測試?件 test.cc,?法中我們實現(xiàn):

  • 對?個聯(lián)系?的信息使? PB 進?序列化,并將序列化結果打印出來。
  • 對序列化后的內(nèi)容使? PB 進?反序列,解析出聯(lián)系?信息并打印出來。
#include <iostream>
#include "contacts.pb.h"
using namespace std;
int main()
{
    string people_str;
    {
        contacts::PeopleInfo people;
        people.set_age(20);
        people.set_name("忘憂");
        if(!people.SerializeToString(&people_str))
        {
            cout << "序列化聯(lián)系人失敗" <<endl;
        }
        cout << "序列化之后的 people_str: " << people_str << endl;
        // 反序列化
        {
            contacts::PeopleInfo people;
            if(!people.ParseFromString(people_str))
            {
                cout << "反序列化聯(lián)系人失敗" <<endl;
            }
            cout << "Parse age: " << people.age() << endl;
            cout << "Parse name: " << people.name() << endl;
        }
    }
    return 0;
}

代碼書寫完成后,編譯 test.cc,生成可執(zhí)行程序:

g++ test.cc contacts.pb.cc -o test -std=c++11 -lprotobuf

執(zhí)?可執(zhí)?程序,可以看? people 經(jīng)過序列化和反序列化后的結果:

  由于 ProtoBuf 是把聯(lián)系?對象序列化成了?進制序列,這?? string 來作為接收?進制序列的容器。所以在終端打印的時候會有換?等?些亂碼顯?。另外相對于 xml 和 JSON 來說,因為PB被編碼成?進制,破解成本增?,ProtoBuf 編碼是相對安全的。

到此這篇關于protobuf簡介及使用流程的文章就介紹到這了,更多相關protobuf使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java Stream 流的使用過程解析

    Java Stream 流的使用過程解析

    這篇文章主要介紹了Java Stream 流的使用過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • Java Set集合及其子類HashSet與LinkedHashSet詳解

    Java Set集合及其子類HashSet與LinkedHashSet詳解

    這篇文章主要介紹了Java Set集合及其子類HashSet與LinkedHashSet詳解,文章通過Set集合存儲原理展開文章主題相關介紹,感興趣的小伙伴可以參考一下
    2022-06-06
  • Java實現(xiàn)棧和最小棧的方法

    Java實現(xiàn)棧和最小棧的方法

    棧(Stack)是一種常用的數(shù)據(jù)結構,其核心特點是先進后出,這篇文章主要介紹了Java實現(xiàn)棧和最小棧的相關操作,需要的朋友可以參考下
    2026-02-02
  • Java大數(shù)字運算之BigInteger

    Java大數(shù)字運算之BigInteger

    在Java中提供了大數(shù)字的操作類,即 java.math.BigInteger 類與 java.math.BigDecimal 類。其中,BigInteger 類是針對大整數(shù)的處理類,這里有Integer 類的解釋,使用方法和實例,需要的朋友可以參考下。
    2017-08-08
  • Java數(shù)據(jù)結構及算法實例:插入排序 Insertion Sort

    Java數(shù)據(jù)結構及算法實例:插入排序 Insertion Sort

    這篇文章主要介紹了Java數(shù)據(jù)結構及算法實例:插入排序 Insertion Sort,本文直接給出實例代碼,代碼中包含詳細注釋,需要的朋友可以參考下
    2015-06-06
  • 詳解Java匿名內(nèi)部類

    詳解Java匿名內(nèi)部類

    這篇文章介紹了Java匿名內(nèi)部類的實現(xiàn),對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-12-12
  • Springboot使用redisson實現(xiàn)分布式鎖的代碼示例

    Springboot使用redisson實現(xiàn)分布式鎖的代碼示例

    在實際項目中,某些場景下可能需要使用到分布式鎖功能,那么實現(xiàn)分布式鎖有多種方式,常見的如mysql分布式鎖、zookeeper分布式鎖、redis分布式鎖,本文介紹springboot如何使用redisson實現(xiàn)分布式鎖,需要的朋友可以參考下
    2023-06-06
  • SpringBoot集成xxl-job實現(xiàn)超牛的定時任務的步驟詳解

    SpringBoot集成xxl-job實現(xiàn)超牛的定時任務的步驟詳解

    XXL-JOB是一個分布式任務調度平臺,其核心設計目標是開發(fā)迅速、學習簡單、輕量級、易擴展,現(xiàn)已開放源代碼并接入多家公司線上產(chǎn)品線,開箱即用,本文給大家介紹了SpringBoot集成xxl-job實現(xiàn)超牛的定時任務,需要的朋友可以參考下
    2023-10-10
  • Java8新特性Stream的完全使用指南

    Java8新特性Stream的完全使用指南

    這篇文章主要給大家介紹了關于Java8新特性Stream的完全使用指南,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Java8具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-05-05
  • 關于springcloud集成nacos遇到的問題

    關于springcloud集成nacos遇到的問題

    這篇文章主要介紹了關于springcloud集成nacos遇到的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評論

利津县| 保德县| 抚州市| 延津县| 丹巴县| 松阳县| 舟山市| 无锡市| 长沙县| 南江县| 镇远县| 合阳县| 原阳县| 阳城县| 莫力| 芷江| 咸丰县| 和龙市| 财经| 大港区| 贞丰县| 溧阳市| 佛学| 房山区| 汉中市| 祁门县| 增城市| 曲靖市| 丹寨县| 建始县| 定结县| 普安县| 合川市| 瑞金市| 平罗县| 鄂托克前旗| 蒲江县| 唐海县| 大洼县| 枣庄市| 平武县|