【ProtoBuf】以 “數據秘語” 筑聯絡:通訊錄項目實戰 1.0 啟步札記

文章目錄

  • 引言
  • 筑路之備:快速上手ProtoBuf
  • 步驟一:創建.proto文件
    • ==?件規范==
    • ==添加注釋==
    • 指定 proto3 語法
    • package 聲明符
    • 定義消息(message)
    • 定義消息字段
    • 【定義聯系人 message】
    • 字段唯一編號的范圍
  • 步驟2:編譯 contacts.proto ?件,?成 C++ ?件
  • 編譯命令
    • 編譯命令?格式為:
    • 編譯 `contacts.proto` ?件命令如下 :
    • 【-I 指定搜索目錄】
  • 編譯 contact.proto 文件效果
    • 【自動生成方法】:
    • 【序列化和反序列化方法】:
  • 步驟3:序列化與反序列化的使?
    • 編譯指令:
  • 小結

在這里插入圖片描述

引言

為何用 “數據秘語” 編織通訊錄?

  • 傳統通訊錄數據的 “困境”:文本格式(如 JSON/CSV)的冗余與解析慢,恰似 “聯絡信箋” 的冗長絮語
  • ProtoBuf 的 “秘語優勢”:二進制壓縮、跨語言兼容,為通訊錄搭建 “高效聯絡通道”
  • 本實戰 1.0 的核心目標:用 ProtoBuf 實現 “聯系人數據的序列化存儲與反序列化讀取”,完成基礎聯絡功能

ProtoBuf的后續學習,將通過項目實戰——書寫通訊錄的方式進行

筑路之備:快速上手ProtoBuf

需求:在快速上?中,會編寫第?版本的通訊錄 1.0。在通訊錄 1.0 版本中,將實現:

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

通過通訊錄 1.0,我們便能了解使?ProtoBuf初步要掌握的內容,以及體驗到 ProtoBuf 的完整使?流程

步驟一:創建.proto文件

?件規范

? 創建 .proto ?件時,?件命名應該使?全?寫字?命名,多個字?之間? _ 連接。 例如lower_snake_case.proto 。
? 書寫 .proto ?件代碼時,應使? 2 個空格的縮進。
我們為通訊錄 1.0 新建?件: contacts.proto

添加注釋

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

指定 proto3 語法

Protocol Buffers 語?版本3,簡稱 proto3,是.proto?件最新的語法版本。proto3 簡化了
Protocol Buffers 語?,既易于使?,?可以在更?泛的編程語?中使?。它允許你使? Java,C++,Python
等多種語??成 protocol buffer 代碼。

.proto?件中,要使?syntax = "proto3";來指定?件語法為 proto3,并且必須寫在除去注釋內容的第??。

注意如果沒有指定,編譯器會使?proto2語法。 在通訊錄 1.0 的 contacts.proto ?件中,可以為?件指定 proto3 語法

syntax = "proto3";

package 聲明符

package 是?個可選的聲明符,能表?.proto?件的命名空間,在項?中要有唯?性。它的作?是為了避免我們定義的消息出現沖突。

可以理解為這個C++,命令空間,避免多個message沖突。在通訊錄 1.0 的 contacts.proto ?件中,可以聲明其命名空間,內容如下:

syntax = "proto3";
package contacts;

定義消息(message)

消息(message): 要定義的結構化對象,我們可以給這個結構化對象中定義其對應的屬性內容。

【問題】:為什么要定義消息?

  • 在?絡傳輸中,我們需要為傳輸雙?定制協議。定制協議說?了就是定義結構體或者結構化數據,?如,tcp,udp 報?就是結構化的。 再?如將數據持久化存儲到數據庫時,會將?系列元數據統??對象組織起來,再進?存儲。

  • 所以 ProtoBuf 就是以 message 的?式來?持我們定制協議字段,后期幫助我們形成類和?法來使?。在通訊錄 1.0 中我們就需要為 聯系? 定義?個 message。
    在這里插入圖片描述
    proto ?件中定義?個消息類型的格式為 :

message 消息類型名{

}

消息類型命令規范:使用駝峰命名法,首字母大寫

定義消息字段

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

  • 字段名稱命名規范:全?寫字?,多個字?之間? _ 連接
  • 字段類型分為:標量數據類型 和 特殊類型(包括枚舉、其他消息類型等)
  • 字段唯?編號:?來標識字段,不能使用相同的字段編號

【定義聯系人 message】

其中,我們必須要把這個字段編號帶上,跟PB特點:高效,序列化,結果更小有關系。跟Protobuf編譯原理有關。

message PeopleInfo{	//建議駝峰string name = 1;//姓名	標識字段編號int32 age = 2;	//年齡
}

該表格展?了定義于消息體中的標量數據類型,以及編譯.proto?件之后?動?成的類中與之對應的字段類型。在這?展?了與 C++ 語?對應的類型。 (了解即可)

在這里插入圖片描述

字段唯一編號的范圍

1 ~ 536,870,911 (2^29 - 1) ,其中 19000 ~ 19999 不可?

19000 ~ 19999 不可?是因為:在 Protobuf 協議的實現中,對這些數進?了預留。如果?要在.proto?件中使?這些預留標識號,例如將 name 字段的編號設置為19000,編譯時就會報警:

// 消息中定義了如下編號,代碼會告警:
// Field numbers 19,000 through 19,999 are reserved for the protobuf
implementation
string name = 19000;

值得?提的是,范圍為 1 ~ 15 的字段編號需要?個字節進?編碼, 16 ~ 2047 內的數字需要兩個字節進?編碼。編碼后的字節不僅只包含了編號,還包含了字段類型。

注意:所以 1 ~ 15 要?來標記出現?常頻繁的字段,要為將來有可能添加的、頻繁出現的字段預留?些出來

步驟2:編譯 contacts.proto ?件,?成 C++ ?件

注意:在使用過程中,如果沒有"顏色亮光",需要下載Protobuf插件

在這里插入圖片描述

編譯命令

編譯命令?格式為:

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

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

protoc --cpp_out=. contacts.proto

【-I 指定搜索目錄】

場景:查找contacts.ptoto(文件名)

在這里插入圖片描述

編譯 contact.proto 文件效果

編譯 contacts.proto ?件后,會?成所選擇語?的代碼,我們選擇的是C++,所以編譯后?成了兩個?件:
contacts.pb.h contacts.pb.cc

對于編譯?成的 C++ 代碼,包含了以下內容 :

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

【自動生成方法】:

在這里插入圖片描述
上述的例?中:

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

【序列化和反序列化方法】:

序列化和反序列化方法,不在Message類中,在消息類的父類MessageLite 中,提供了讀寫消息實例的方法,包括了序列化方法和反序列化方法。Message類繼承MessageLite父類的屬性和方法

在這里插入圖片描述
注意:

  • 序列化的結果為?進制字節序列,???本格式。
  • 以上三種序列化的?法沒有本質上的區別,只是序列化后輸出的格式不同,可以供不同的應?場景使?。
  • 序列化的 API 函數均為const成員函數,因為序列化不會改變類對象的內容, ?是將序列化的結果保存到函數?參指定的地址中。
  • 詳細 message API 可以參?完整列表

步驟3:序列化與反序列化的使?

創建?個測試?件 main.cc,?法中我們實現:

  • 對?個聯系?的信息使? PB 進?序列化,并將結果打印出來。
  • 對序列化后的內容使?PB進?反序列,解析出聯系?信息并打印出來。

main.cc

#include<iostream>
#include"contacts.pb.h"int main()
{std::string people_str;{// 對一個聯系人使用 PB 進行序列化,并將結果打印出來contacts::PeopleInfo people; // 定義對象people.set_name("張三"); // 設置姓名people.set_age(20); // 設置年齡// 使用正確的序化方法if(!people.SerializeToString(&people_str)){std::cerr << "Failed to serialize people." << std::endl;return -1;}std::cout << "Serialized data: " << people_str << std::endl;}{// 對一個聯系人使用 PB 進行反序列化,并將結果打印出來contacts::PeopleInfo people; // 定義對象// 使用正確的反序列化方法if(!people.ParseFromString(people_str)){std::cerr << "Failed to parse people." << std::endl;return -1;}std::cout << "Name: " << people.name() << std::endl; // 獲取姓名std::cout << "Age: " << people.age() << std::endl; // 獲取年齡}return 0;}

編譯指令:

g++ main.cc contacts.pb.cc -o TestPb -std=c++11 -lprotobuf
  • -lprotobuf:必加,不然會有鏈接錯誤。
  • -std=c++11:必加,使?C++11語法。

執? TestPb,可以看? people 經過序列化和反序列化后的結果:

在這里插入圖片描述
由于ProtoBuf是把聯系?對象序列化成了?進制序列,這?? string 來作為接收?進制序列的容器。所以在終端打印的時候會有換?等?些亂碼顯?。

所以相對于 xml JSON 來說,因為被編碼成?進制,破解成本增?,ProtoBuf 編碼是相對安全的。

在這里插入圖片描述

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

小結

當你用 ProtoBuf 的 “數據秘語” 織就通訊錄的存儲與讀取,這座精簡高效的聯絡小筑,便已在你手中落成。

1.0 的啟步札記雖止于此,卻為你推開了數據通信的門,更精彩的 “秘語續篇”,正待后續續寫。

在這里插入圖片描述

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

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

相關文章

在 macOS 下升級 Python 幾種常見的方法

在 macOS 下升級 Python 有幾種常見的方法&#xff0c;具體取決于你最初是如何安裝 Python 的。了解你的安裝方式是關鍵。 首先&#xff0c;你需要知道你當前 Python 版本以及它的安裝路徑。 檢查 Python 版本&#xff1a; python --version # 可能指向 Python 2.x python3 …

Linux 入門到精通,真的不用背命令!零基礎小白靠「場景化學習法」,3 個月拿下運維 offer,第二十五天

三、Shell腳本編程 Shell腳本語言的運算 算數運算 shell支持算術運算&#xff0c;但只支持整數&#xff0c;不支持小數 Bash中的算術運算 -- 加法運算 -- - 減法運算 -- * 乘法運算 -- / 除法運算 -- % 取模&#xff0c;即取余數 -- ** 乘方 ? #乘法符號在有些場景需要轉…

SpringAI系列---【多租戶記憶和淘汰策略】

1.多租戶工作原理 2.引入jdbc的pom spring官網鏈接&#xff1a;https://docs.spring.io/spring-ai/reference/api/chat-memory.html&#xff0c;推薦使用官網的jdbc。 阿里巴巴ai鏈接&#xff1a;https://github.com/alibaba/spring-ai-alibaba/tree/main/community/memories j…

Linux gzip 命令詳解:從基礎到高級用法

Linux gzip 命令詳解&#xff1a;從基礎到高級用法 在 Linux 系統中&#xff0c;文件壓縮與解壓縮是日常運維和文件管理的常見操作。gzip&#xff08;GNU Zip&#xff09;作為一款經典的壓縮工具&#xff0c;憑借其高效的壓縮算法和簡潔的使用方式&#xff0c;成為 Linux 用戶處…

Redis有什么優點和缺點?

優點&#xff1a;極致性能&#xff1a; 基于內存操作和高效的單線程 I/O 模型&#xff0c;讀寫速度極快。數據結構豐富&#xff1a; 支持多種數據結構&#xff0c;如 String、Hash、List、Set、ZSet、Stream、Geo 等&#xff0c;編程模型靈活。持久化與高可用&#xff1a; 提供…

NestJS 3 分鐘搭好 MySQL + MongoDB,CRUD 復制粘貼直接運行

基于上一篇內容《為什么現代 Node 后端都選 NestJS TypeScript&#xff1f;這組合真香了》&#xff0c;這篇文章繼續寫數據庫的連接。 所以今天把MySQL、MongoDB全接上&#xff0c;做個小實例。朋友們項目里用什么數據庫可以視情況而定。 這里的功能分別為&#xff1a; MySQ…

用了企業微信 AI 半年,這 5 個功能讓我徹底告別重復勞動

每天上班不是在整理會議紀要&#xff0c;就是在翻聊天記錄找文件&#xff0c;寫文檔還要自己摳數據…… 這些重復勞動是不是也在消耗你的時間&#xff1f;作為用了企業微信 AI 功能半年的 “老用戶”&#xff0c;我必須說&#xff1a;企業微信 AI 的這 5 個功能&#xff0c;真的…

從入門到高手,Linux就應該這樣學【好書推薦】

從入門到高手&#xff0c;請這樣學Linux 一、Linux基礎與終端操作 1.1 Linux簡介 Linux 是一種開源的類 Unix 操作系統&#xff0c;以其穩定性、安全性和高效性被廣泛應用于服務器、嵌入式系統及開發環境中。掌握基本命令和操作技巧是 Linux 學習的關鍵。 1.2 終端基礎 打開…

【數據可視化-104】安徽省2025年上半年GDP數據可視化分析:用Python和Pyecharts打造炫酷大屏

&#x1f9d1; 博主簡介&#xff1a;曾任某智慧城市類企業算法總監&#xff0c;目前在美國市場的物流公司從事高級算法工程師一職&#xff0c;深耕人工智能領域&#xff0c;精通python數據挖掘、可視化、機器學習等&#xff0c;發表過AI相關的專利并多次在AI類比賽中獲獎。CSDN…

組件庫UI自動化

一、背景 背景&#xff1a; 組件庫全局改動場景多&#xff0c;組件之間耦合場景多–時常需要全場景回歸組件庫demo有200多個&#xff0c;手動全局回歸耗時耗力細微偏差純視覺無法辨別 可行性分析&#xff1a; 組件庫功能占比 L1&#xff08;視覺層&#xff09;&#xff1a;圖片…

面試題:JVM與G1要點總結

一.Java內存區域 1.運行時數據區的介紹 2.站在線程的角度看Java內存區域 3.深入分析堆和棧的區別 4.方法的出入棧和棧上分配、逃逸分析及TLAB 5.虛擬機中的對象創建步驟 6.對象的內存布局 1.運行時數據區的介紹 運行時數據區的類型&#xff1a;程序計數器、Java虛擬機棧、本地方…

車輛安全供電系統開發原則和實踐

摘要在汽車行業中&#xff0c;安全應用的重要性在不斷提升&#xff0c;例如受車輛自動化發展以及機械備用系統重要性降低的影響。為應對這些趨勢&#xff0c;安全相關的電氣和 / 或電子系統&#xff08;E/E 系統&#xff09;的電源輸入必須由供電系統來保障&#xff0c;這使得功…

WebSocket客戶端庫:websocket-fruge365

&#x1f680; 從零開始打造一個WebSocket客戶端庫&#xff1a;websocket-fruge365 &#x1f4d6; 前言 在現代Web開發中&#xff0c;實時通信已經成為不可或缺的功能。無論是聊天應用、實時數據監控&#xff0c;還是在線協作工具&#xff0c;WebSocket都扮演著重要角色。然而…

rocketmq批量執行跑批任務報錯

rocketmq批量執行跑批任務&#xff0c;報下面的錯誤&#xff0c;怎么處理一下呢&#xff1f;是修改配置還是修改代碼還是&#xff1f; org.apache.rocketmq.client.exception.MQBrokerException: CODE: 215 DESC: [FLOW]client has exhausted the send quota for the current …

大語言模型(LLM)簡介與應用分享

1. 什么是大語言模型&#xff08;LLM&#xff09; 大語言模型&#xff08;Large Language Model&#xff0c;簡稱 LLM&#xff09;是基于 深度學習 和 海量文本數據 訓練而成的人工智能模型。 采用 Transformer 架構參數規模巨大&#xff08;數十億到數千億&#xff09;能夠 理…

【算法筆記】選擇排序、插入排序、冒泡排序、二分查找問題

算法的筆記&#xff0c;直接上代碼&#xff0c;思路和問題這些&#xff0c;都在代碼注釋上面 1、工具類 為了生成測試代碼和比較器&#xff0c;專門寫了一個數組工具類&#xff0c;代碼如下&#xff1a; /*** 數組工具類*/ public class ArrUtil {/*** 生成隨機數組* 長度是[0,…

行業分享丨基于SimSolid的大型汽車連續沖壓模具剛度分析

*本文投稿自機械零部件制造業用戶 汽車連續模具的剛度直接決定了沖壓件質量&#xff08;尺寸精度、表面缺陷&#xff09;與模具壽命。傳統有限元分析&#xff08;FEA&#xff09;在面對大型復雜模具裝配體時&#xff0c;存在網格劃分困難、計算資源消耗大、周期長等瓶頸。本文以…

用AI生成的html頁面設計放到到Axure上實現再改造的方法

要將 AI 生成的 HTML 原型導入 Axure&#xff0c;該方法的核心邏輯是以 Figma 為 “中間橋梁”&#xff08;因 Axure 無法直接讀取 HTML&#xff0c;需通過 Figma 轉換格式&#xff09;&#xff0c;分 3 步即可完成&#xff0c;以下是詳細操作指南&#xff08;含每步目標、具體…

從入門到實戰:Linux sed命令全攻略,文本處理效率翻倍

從入門到實戰&#xff1a;Linux sed命令全攻略&#xff0c;文本處理效率翻倍 文章目錄從入門到實戰&#xff1a;Linux sed命令全攻略&#xff0c;文本處理效率翻倍一、認識sed&#xff1a;什么是流編輯器&#xff1f;二、吃透sed工作原理&#xff1a;為什么它能高效處理文本&am…

TIOBE 8月編程語言榜深度解析:Python占比突破26%,Perl成最大黑馬

根據TIOBE最新發布的2025年8月編程語言排行榜&#xff0c;一場靜默的技術變革正在上演&#xff1a;Python以26.14%的占比首次突破26%大關&#xff0c;連續12個月穩居榜首。這一數據不僅刷新了Python自身的歷史紀錄&#xff0c;更成為TIOBE指數自2001年創立以來的最高單語言占比…