Protocol Buffers 基本介紹及基本文法
引言
在現代軟體開發中,資料交換和儲存是至關重要的,而選擇合適的序列化協定對提高效能和效率具有重要意義。 Protocol Buffers(通常稱為Protobuf)是Google 開發的語言中立、平台中立、可擴展的序列化結構資料的方法。本文將介紹Protocol Buffers 的基本概念、與其他序列化協定的差異、基本語法,並提供範例程式碼,幫助你快速入門。
一、什麼是Protocol Buffers
Protocol Buffers 是一種輕量級的序列化格式,主要用於結構化資料的序列化與反序列化。它允許開發者定義資料結構,然後自動產生程式碼以便在多種程式語言之間傳輸資料。
1.1 特性
- 高效率:Protobuf 使用緊湊的二進位格式,相較於其他文字格式(如JSON 和XML),在儲存和傳輸時更小且更快。
- 語言中立:支援多種程式語言,包括C++、Java、Python、Go、Ruby 等。
- 向後相容性:允許你在不破壞現有服務的情況下,修改資料結構,支援欄位的新增和移除。
- 簡單易用:使用簡潔的語法定義資料結構,自動產生對應的程式碼。
二、Protocol Buffers 與其他序列化協議的區別
在選擇序列化協定時,了解不同協定的優缺點是至關重要的。以下是Protocol Buffers 與其他常見序列化協議的比較:
2.1 與JSON 的比較
- 格式:JSON 是文字格式,易於閱讀和調試;而Protobuf 是二進位格式,更緊湊,但不易於人類直接讀取。
- 效能:Protobuf 在序列化和反序列化性能上通常優於JSON,特別是在處理大量資料時。
- 資料型別支援:JSON 支援基本資料類型,而Protobuf 提供了更多的資料類型支持,如枚舉、巢狀結構等。
- 模式(Schema):Protobuf 強制要求定義資料結構(模式),而JSON 是無模式的。
2.2 與XML 的比較
- 格式:XML 是文字格式,結構複雜且冗長;Protobuf 則使用二進位格式,資料更為緊湊。
- 解析速度:Protobuf 的解析速度通常比XML 快,因為XML 需要解析器處理標記和屬性。
- 類型安全:Protobuf 提供型別定義,確保資料的安全性,而XML 只是字串,沒有型別限制。
- 使用場景:雖然XML 更適合表示文檔型數據,但在高效的網路通訊和儲存方面,Protobuf 更為適合。
三、Protocol Buffers 的基本文法
3.1 定義資料結構
使用Protobuf 需要定義 .proto
文件,描述資料結構及其類型。以下是一個簡單的 .proto
文件範例:
syntax = "proto3"; package example; // 定義一個訊息message Person { string name = 1; // 姓名int32 id = 2; // ID string email = 3; // 信箱 }
3.2 語法解析
- 文法版本:
syntax = "proto3";
指定使用的Protobuf 語法版本。目前最新的是proto3。 - 包名:
package example;
定義了訊息所屬的包。 - 訊息類型:使用
message
關鍵字定義一個訊息,類似於類別的定義。 - 欄位:每個欄位都有類型、名稱和唯一的數字識別碼。標識符用於序列化時區分字段。
3.3 基本資料類型
Protobuf 支援多種基本資料類型,包括:
int32
:32 位元整數int64
:64 位元整數uint32
:無符號32 位元整數uint64
:無符號64 位元整數sint32
:有符號32 位元整型,採用ZigZag 編碼sint64
:有符號64 位元整數fixed32
、fixed64
:固定長度的整數bool
:布林值string
:字串bytes
:位元組數組
3.4 嵌套訊息和枚舉
Protobuf 也支援巢狀訊息和枚舉類型,以下是範例:
message Company { string name = 1; repeated Person employees = 2; // 多個員工} enum Role { UNKNOWN = 0; DEVELOPER = 1; MANAGER = 2; }
- 嵌套訊息:使用
repeated
關鍵字表示一個欄位可以包含多個值(如陣列)。 - 列舉:使用
enum
定義有限的值集合,方便表示狀態或角色。
四、使用Protocol Buffers 的範例
4.1 安裝Protocol Buffers
首先,請確保安裝了Protocol Buffers 編譯器 protoc
和對應的語言插件。以Go 為例:
# 安裝protoc sudo apt install -y protobuf-compiler # 安裝Go 插件go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
4.2 建立範例項目
建立一個簡單的Protobuf 範例專案結構:
protobuf-example/ ├── proto/ │ └── example.proto ├── main.go
4.3 定義資料結構
在 proto/example.proto
中定義資料結構:
syntax = "proto3"; package example; message Person { string name = 1; int32 id = 2; string email = 3; }
4.4 產生程式碼
在專案目錄中產生Go 程式碼:
protoc --go_out=. --go-grpc_out=. proto/example.proto
4.5 實作程式碼
在 main.go
中實現序列化和反序列化:
package main import ( "log" "github.com/golang/protobuf/proto" pb "protobuf-example/proto" ) func main() { // 建立一個Person 實例person := &pb.Person{ Name: "ivanzhang" , Id: 101, Email: "ivanzhang@ztoutup.com", } // 序列化data, err := proto.Marshal(person) if err != nil { log.Fatalf("failed to marshal: %v", err ) } // 反序列化newPerson := &pb.Person{} if err := proto.Unmarshal(data, newPerson); err != nil { log.Fatalf("failed to unmarshal: %v", err) } //輸出結果log.Printf("Name: %s, ID: %d, Email: %s", newPerson.Name, newPerson.Id, newPerson.Email) }
4.6 運行範例
在專案目錄中執行程式碼:
go run main.go
輸出:
Name: ivanzhang, ID: 101, Email: ivanzhang@ztoutup.com
五、總結
Protocol Buffers 是一種高效、靈活的序列化協議,適用於現代應用程式的資料傳輸。本文介紹了Protocol Buffers 的基本概念、與其他序列化協議的比較、基本語法及範例程式碼。透過掌握Protobuf,你可以更有效率地處理結構化數據,提升網路通訊的效能和可靠性。
如有疑問或建議,請在下方留言。感謝閱讀!希望這篇文章能幫助你更能理解並使用Protocol Buffers。
參考連結: