中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

外國優(yōu)秀網站設計青島關鍵詞優(yōu)化平臺

外國優(yōu)秀網站設計,青島關鍵詞優(yōu)化平臺,哪些網站做寫字樓出租,山西百度網站建設Protobuf 3 入門 1. 什么是序列化? 1.1 概念 序列化(Serialization 或 Marshalling) 是指將數(shù)據(jù)結構或對象的狀態(tài)轉換成可存儲或傳輸?shù)母袷健7聪虿僮鞣Q為反序列化(Deserialization 或 Unmarshalling),它…

Protobuf 3 入門

1. 什么是序列化?

1.1 概念

序列化(Serialization 或 Marshalling) 是指將數(shù)據(jù)結構或對象的狀態(tài)轉換成可存儲或傳輸?shù)母袷?/strong>。反向操作稱為反序列化(Deserialization 或 Unmarshalling),它的作用是將序列化的數(shù)據(jù)恢復成原始的數(shù)據(jù)結構或對象。

簡單來說,序列化就像“打包”,反序列化就像“解包”。

2.1 為什么需要序列化?

在計算機系統(tǒng)中,數(shù)據(jù)通常是以內存中的對象(如 struct、class)形式存在的,而內存數(shù)據(jù)不能直接在不同程序之間傳輸,必須先轉換成可存儲或可傳輸?shù)母袷?。序列化的主要用途包?#xff1a;

  1. 數(shù)據(jù)存儲:將數(shù)據(jù)保存到文件、數(shù)據(jù)庫等,例如:
    • 日志文件
    • 配置文件(如 JSON、YAML)
    • 持久化存儲(如 Redis、MongoDB)
  2. 數(shù)據(jù)傳輸:在不同進程或網絡之間傳輸數(shù)據(jù),例如:
    • 前端和后端通信(Web API)
    • 微服務之間的通信
    • 遠程調用(RPC,如 gRPC)
  3. 數(shù)據(jù)緩存:比如將復雜的對象序列化后存入 Redis,提高訪問速度。
  4. 跨語言兼容:不同編程語言的數(shù)據(jù)結構不一樣,序列化后可以在不同語言之間傳輸數(shù)據(jù)。

3.1 序列化的方式

不同的序列化格式適用于不同的應用場景,常見的格式包括:

格式特點可讀性序列化速度數(shù)據(jù)大小適用場景
JSON文本格式,廣泛使用可讀適中較大Web API,前端后端通信
XML結構化文本,標簽冗余可讀早期 Web API,配置文件
YAML結構更簡潔,適合人閱讀可讀適中較大配置文件(Kubernetes、Docker)
ProtobufGoogle 開發(fā)的高效二進制格式不可讀微服務、gRPC、高性能應用
MessagePack類似 JSON,但體積更小不可讀移動端、嵌入式系統(tǒng)
ThriftFacebook 開發(fā)的高效序列化格式不可讀分布式系統(tǒng),RPC
Avro適用于大數(shù)據(jù)(如 Hadoop)不可讀適中大數(shù)據(jù)處理
BSONMongoDB 的序列化格式不可讀適中適中MongoDB 數(shù)據(jù)存儲

2. 什么是 Protobuf?

2.1 概念

Protobuf(Protocol Buffers)是 Google 開發(fā)的一種高效、跨平臺、可擴展數(shù)據(jù)序列化協(xié)議。它可以將數(shù)據(jù)轉換為緊湊的二進制格式,用于不同系統(tǒng)之間進行高效的數(shù)據(jù)傳輸和存儲。

簡單理解:

  • 它類似于 JSON,但比 JSON 體積更小、速度更快。
  • 它類似于 XML,但格式更緊湊、解析更高效。
  • 它適用于微服務、RPC(遠程調用)、數(shù)據(jù)存儲等高性能場景。

2.2 為什么使用 Protobuf?

特點ProtobufJSONXML
格式二進制文本文本
體積最小較大最大
解析速度最快一般最慢
可讀性不可讀可讀可讀
跨語言支持
支持 RPC是(gRPC)

如果你的項目涉及:

  • 高性能數(shù)據(jù)通信(微服務、RPC、物聯(lián)網、游戲服務器)
  • 跨語言數(shù)據(jù)傳輸(Go、Java、Python、C++、Rust 等)
  • 大規(guī)模數(shù)據(jù)存儲(日志、數(shù)據(jù)庫、緩存)

那么 Protobuf 是比 JSON、XML 更好的選擇

2.3 Protobuf 的使用場景

  1. 微服務通信(gRPC)
    • 適用于 Go、Java、Python、C++ 等語言的微服務之間高效通信。
    • 結合 gRPC 使用,可以比傳統(tǒng) REST API 更快。
  2. 數(shù)據(jù)存儲
    • 存儲日志、緩存數(shù)據(jù)(如存入 Redis)時,Protobuf 體積小,能節(jié)省存儲空間
  3. 跨語言數(shù)據(jù)交換
    • 由于 Protobuf 支持多種編程語言,可以在不同語言的系統(tǒng)之間進行高效數(shù)據(jù)傳輸。
  4. 移動端和 IoT(物聯(lián)網)
    • 移動端和 IoT 設備通常帶寬和存儲受限,Protobuf 適用于傳輸小體積數(shù)據(jù),提高性能。

3. 簡單解釋 Protobuf 例子

3.1 Protobuf 文件 simple.proto

syntax = "proto3"; // 使用 proto3 語法message SearchRequest {  // 定義一個數(shù)據(jù)結構(類似 JSON 對象)string query = 1;      // 搜索關鍵詞(字符串)int32 page_number = 2; // 頁碼(整數(shù))int32 result_per_page = 3; // 每頁返回的結果數(shù)(整數(shù))
}

解釋

  • syntax = "proto3"; 指定使用 proto3 語法。
  • message SearchRequest 定義了一個數(shù)據(jù)結構(類似 JSON 對象)。
  • 每個字段的格式:
    • 類型string、int32
    • 字段名稱query、page_number、result_per_page
    • 字段編號1、2、3,用于唯一標識字段,不能重復)

3.2 編譯 Protobuf 代碼

Protobuf 需要編譯后才能用于編程語言(Go、Java、Python 等)。 在終端運行:

protoc --go_out=. simple.proto
  • protoc 是 Protobuf 編譯器
  • --go_out=. 表示生成 Go 代碼,并存放在當前目錄
  • simple.proto 是需要編譯的 Protobuf 文件

不同語言對應的參數(shù):

語言編譯參數(shù)
C++--cpp_out=.
Java--java_out=.
Python--python_out=.
C#--csharp_out=.
Rust--rust_out=.

最終會生成 simple.pb.go,這個文件包含 Go 代碼,用于操作 SearchRequest 結構。

3.3 生成的 Go 代碼

編譯后會生成如下 Go 結構:

type SearchRequest struct {Query         string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"`PageNumber    int32  `protobuf:"varint,2,opt,name=page_number,json=pageNumber,proto3" json:"page_number,omitempty"`ResultPerPage int32  `protobuf:"varint,3,opt,name=result_per_page,json=resultPerPage,proto3" json:"result_per_page,omitempty"`
}

解釋

  • SearchRequeststruct,對應 .proto 文件中的 message SearchRequest
  • Query、PageNumber、ResultPerPage 變量對應 .proto 里的字段。
  • protobuf:"..." 里的信息用于 Protobuf 序列化和解析。

3.4 如何使用這個 Go 結構

package mainimport ("fmt""google.golang.org/protobuf/proto"
)func main() {// 創(chuàng)建 SearchRequest 實例request := &SearchRequest{Query:         "golang protobuf",PageNumber:    1,ResultPerPage: 10,}// **序列化**data, _ := proto.Marshal(request)// **反序列化**newRequest := &SearchRequest{}proto.Unmarshal(data, newRequest)fmt.Println(newRequest) // 輸出: {Query:golang protobuf PageNumber:1 ResultPerPage:10}
}

解釋

  1. 創(chuàng)建 SearchRequest 結構,并填充數(shù)據(jù)。
  2. 使用 proto.Marshal(request) 序列化,轉換成二進制格式(適合網絡傳輸)。
  3. 使用 proto.Unmarshal(data, newRequest) 反序列化,把二進制恢復成 Go 結構。

4. Protobuf 的數(shù)據(jù)類型

4.1 標量數(shù)據(jù)類型(Scalar Types)

Protobuf 提供了一些常見的基本數(shù)據(jù)類型,對應不同語言的變量類型。

4.1.1 數(shù)值類型
Protobuf 類型說明適用場景
int3232 位整數(shù)(默認編碼)適用于較小的整數(shù)
int6464 位整數(shù)(默認編碼)適用于較大的整數(shù)
uint32無符號 32 位整數(shù)適用于只能為正數(shù)的情況
uint64無符號 64 位整數(shù)適用于大數(shù)且不允許負數(shù)
sint3232 位有符號整數(shù)(ZigZag 編碼)適用于可能包含負數(shù)的整數(shù)
sint6464 位有符號整數(shù)(ZigZag 編碼)適用于包含負數(shù)的長整數(shù)
fixed3232 位整數(shù)(固定長度編碼)適用于數(shù)值分布較均勻的場景
fixed6464 位整數(shù)(固定長度編碼)適用于較大的定長整數(shù)
sfixed3232 位有符號整數(shù)(固定長度編碼)適用于負數(shù)較多的場景
sfixed6464 位有符號整數(shù)(固定長度編碼)適用于較大的負數(shù)

區(qū)別:

  • int32/int64:默認使用 Varint 編碼(數(shù)據(jù)小的時候占用字節(jié)更少)。
  • sint32/sint64:使用 ZigZag 編碼,負數(shù)編碼更高效。
  • fixed32/fixed64:使用固定長度存儲,適合數(shù)值分布均勻的情況。
  • sfixed32/sfixed64:固定長度的有符號整數(shù)。
4.1.2 浮點數(shù)類型
Protobuf 類型說明適用場景
float32 位浮點數(shù)適用于存儲小數(shù)
double64 位浮點數(shù)適用于更高精度的小數(shù)

注意:

  • float4 個字節(jié),精度有限。
  • double8 個字節(jié),適用于更高精度計算。
4.1.3 布爾類型
Protobuf 類型說明適用場景
bool布爾值 (true/false)適用于開關、狀態(tài)等

示例:

message Example {bool is_active = 1; // true or false
}
4.1.4 字符串和字節(jié)類型
Protobuf 類型說明適用場景
stringUTF-8 編碼的字符串存儲文本信息
bytes原始字節(jié)數(shù)據(jù)適用于存儲二進制數(shù)據(jù)(如文件、圖片等)

示例:

message Example {string name = 1;bytes file_data = 2;
}

注意:

  • string 只能存儲 文本(UTF-8 編碼)。
  • bytes 可以存儲 任意二進制數(shù)據(jù)(如圖片、視頻等)。

4.2 復雜數(shù)據(jù)類型

4.2.1 數(shù)組(Repeated)

使用 repeated 關鍵字表示 列表/數(shù)組

message Example {repeated string hobbies = 1;repeated int32 scores = 2;
}
  • repeated string hobbies = 1; → 表示字符串數(shù)組
  • repeated int32 scores = 2; → 表示整數(shù)數(shù)組

注意

  • 在 Protobuf 3 中,repeated 類型默認是可選的,不需要額外的 optional 關鍵字。
4.2.2 鍵值對(Map)

Protobuf 3 提供 map<K, V> 類型來存儲鍵值對

message Example {map<string, int32> scores = 1; // key: string, value: int32
}
  • map<string, int32> 表示 鍵為字符串,值為整數(shù) 的字典。
  • 生成代碼后,會轉換成 Go 語言的 map[string]int32。
4.2.3 枚舉類型(Enum)
enum Status {UNKNOWN = 0;  // 枚舉必須從 0 開始ACTIVE = 1;INACTIVE = 2;
}message User {Status status = 1;
}
  • enum 只能用于定義固定的值(類似 int)。
  • 第一個枚舉值必須是 0,防止解析錯誤。
4.2.4 嵌套 Message
message Address {string city = 1;string street = 2;
}message Person {string name = 1;Address address = 2; // 直接嵌套 Address
}
  • Person 結構里包含 Address 結構,可以用于復雜數(shù)據(jù)存儲。

4.3 Protobuf 類型與不同語言的對應關系

Protobuf 類型GoJavaPythonC++
int32int32intintint32_t
int64int64longintint64_t
floatfloat32floatfloatfloat
doublefloat64doublefloatdouble
boolboolbooleanboolbool
stringstringStringstrstd::string
bytes[]bytebyte[]bytesstd::string
map<K,V>map[K]VMap<K,V>dictstd::map<K,V>
repeated[]TList<T>liststd::vector<T>

4.4 Protobuf 3 語法示例

syntax = "proto3";message Person {string name = 1;int32 age = 2;bool is_active = 3;repeated string hobbies = 4;map<string, int32> scores = 5;
}

這個 Person 結構包含:

  • string name → 姓名
  • int32 age → 年齡
  • bool is_active → 是否激活
  • repeated string hobbies → 興趣愛好(數(shù)組)
  • map<string, int32> scores → 課程成績(鍵值對)

5. Protobuf 其他字段

5.1 Oneof(互斥字段)

5.1.1 什么是 oneof

oneof 關鍵字用于定義一組互斥字段,即同一時間只能有一個字段被設置。它的作用類似于 C 語言的 union,但比 union 更智能,可以判斷當前設置的是哪個字段

5.1.2 為什么要用 oneof

proto3 版本中,所有字段都有默認值,比如:

message Example {int64 id = 1;
}
  • 如果 id 沒有被設置,默認值是 0。
  • 但如果 id 被顯式設置為 0,你就無法判斷這個 0 是默認值,還是用戶真的設置了 0

oneof 解決了這個問題,因為它提供了一個字段狀態(tài)檢查功能,讓你可以判斷哪個字段被設置了。

5.1.3 oneof 語法
message Response {oneof result {string success_message = 1; // 成功時的消息int32 error_code = 2; // 失敗時的錯誤碼}
}
  • oneof 內的字段是互斥的,最多只能設置一個。
  • 如果 success_message 被設置,error_code 就不能被設置,反之亦然。
  • 如果不設置任何字段,oneof 字段為空。

適用場景

  • API 響應(成功返回 success_message,失敗返回 error_code)。
  • 狀態(tài)表示(例如訂單可能是“待支付”或“已完成”,但不能同時處于這兩個狀態(tài))。
5.1.4 oneof 在 Go 語言中的使用

Protobuf 生成的 Go 代碼會使用 isXxx() 方法 來判斷哪個字段被賦值。

示例:Go 代碼

package mainimport ("fmt""google.golang.org/protobuf/proto"
)// 假設 Protobuf 生成的 Go 結構如下:
type Response struct {// 這是 oneof 生成的字段Result isResponse_Result `protobuf_oneof:"result"`
}type isResponse_Result interface {isResponse_Result()
}type Response_SuccessMessage struct {SuccessMessage string
}type Response_ErrorCode struct {ErrorCode int32
}// 實現(xiàn) isResponse_Result 接口
func (*Response_SuccessMessage) isResponse_Result() {}
func (*Response_ErrorCode) isResponse_Result() {}func main() {// **成功時返回 success_message**resp1 := &Response{Result: &Response_SuccessMessage{SuccessMessage: "Operation successful"}}// **失敗時返回 error_code**resp2 := &Response{Result: &Response_ErrorCode{ErrorCode: 404}}// 判斷是哪個字段被設置switch v := resp1.Result.(type) {case *Response_SuccessMessage:fmt.Println("Success:", v.SuccessMessage)case *Response_ErrorCode:fmt.Println("Error:", v.ErrorCode)}switch v := resp2.Result.(type) {case *Response_SuccessMessage:fmt.Println("Success:", v.SuccessMessage)case *Response_ErrorCode:fmt.Println("Error:", v.ErrorCode)}
}

輸出

Success: Operation successful
Error: 404
  • oneof 生成了 isResponse_Result 接口,允許我們判斷哪個字段被設置。
  • switch v := resp.Result.(type) 語法用于檢查當前 oneof 字段的類型。
5.1.5 oneof 的應用場景
  • REST API / gRPC 響應(成功返回數(shù)據(jù),失敗返回錯誤碼)
  • 訂單狀態(tài)未支付 / 已支付
  • 用戶身份驗證郵箱登錄 / 手機號登錄
  • 存儲不同類型的數(shù)據(jù)文本 / 圖片 / 視頻

5.2 Reserved(保留字段)

5.2.1 什么是reserved

在 Protobuf 3 中,reserved 關鍵字用于保留字段編號或名稱,防止將來代碼演進時誤用已刪除的字段。
這可以避免 API 變更時的兼容性問題,確保舊數(shù)據(jù)不會被錯誤解析。

5.2.2 為什么需要 reserved

當你刪除或修改字段時,如果不使用 reserved,那么:

  1. 未來新添加的字段可能意外復用舊的字段編號,導致數(shù)據(jù)解析出錯。
  2. 舊數(shù)據(jù)仍然可能使用被刪除的字段,導致意外行為。
5.2.3 reserved 語法

你可以用 reserved 關鍵字保留字段編號或名稱,防止后續(xù)被重新使用。

保留字段編號

message User {reserved 2, 4 to 6; // 不能再使用編號 2、4、5、6
}
  • 以后不能再使用 2、4、5、6 作為字段編號。
  • 如果后續(xù)嘗試用 field = 2;,編譯時會報錯。

保留字段名稱

message User {reserved "old_name", "deprecated_field"; // 不能再使用這些字段名
}
  • 以后不能再使用 “old_name” 和 “deprecated_field” 作為字段名。

同時保留編號和名稱

message User {reserved 2, 4 to 6;reserved "old_name", "deprecated_field";
}
  • 這樣可以同時保留編號和字段名稱,防止意外復用。
5.2.4 reserved 作用
  • 避免舊數(shù)據(jù)解析錯誤:如果編號被誤用,舊數(shù)據(jù)可能被錯誤解析。
  • 防止 API 兼容性問題:如果 API 變更,保留字段可以確保舊客戶端不會收到無效數(shù)據(jù)。
  • 讓代碼更可維護:明確告訴后續(xù)開發(fā)者哪些字段不能使用。

5.3 Any(存儲任意數(shù)據(jù))

5.3.1 什么是 Any

Any 是 Protobuf 3 提供的一種特殊類型,允許存儲任意類型的 Protobuf 消息,適用于動態(tài)數(shù)據(jù)場景。
它可以在不修改 .proto 結構的情況下,支持不同類型的數(shù)據(jù),類似于 JSON 里的 objectmap<string, any>。

5.3.2 Any 的作用
  • 存儲動態(tài)數(shù)據(jù):如果一個字段的類型可能變化(例如可能是 UserOrder),可以使用 Any 而不需要改 .proto 文件。
  • 實現(xiàn)靈活的 API 設計:適用于插件系統(tǒng)、事件系統(tǒng)、日志系統(tǒng),讓不同的子系統(tǒng)傳遞不同的數(shù)據(jù)結構。
  • 避免頻繁修改 Protobuf 定義:當不同的客戶端需要傳輸不同的數(shù)據(jù)類型時,使用 Any 可以減少 API 變更的影響。
5.3.3 Any 的基本用法

(1)導入 Any 類型

Any 需要導入 google/protobuf/any.proto

import "google/protobuf/any.proto"; // 引入 Any 類型message Response {string message = 1; google.protobuf.Any data = 2; // 存儲任意類型
}
  • message 是普通字段,存儲文本信息。
  • dataAny 類型,可以存儲任何 Protobuf 消息。

(2)嵌套不同的消息

假設你有兩種不同的消息 UserOrder

message User {string name = 1;int32 age = 2;
}message Order {int32 order_id = 1;double price = 2;
}message Response {string message = 1;google.protobuf.Any data = 2; // 可以存儲 User 或 Order
}
  • data 字段可以存儲 UserOrder,而不需要修改 Response 結構。
  • 這樣,Response 可以在不同場景下使用,不受數(shù)據(jù)類型影響
5.3.4 Any 在 Go 語言中的使用

(1)安裝 Protobuf 依賴

在 Go 代碼中,需要 protoanypb(處理 Any 類型):

go get google.golang.org/protobuf/proto
go get google.golang.org/protobuf/types/known/anypb

(2)Go 代碼示例

package mainimport ("fmt""google.golang.org/protobuf/proto""google.golang.org/protobuf/types/known/anypb"
)// 定義 User 和 Order 結構
type User struct {Name stringAge  int32
}type Order struct {OrderId int32Price   float64
}// Response 結構,包含 Any 字段
type Response struct {Message stringData    *anypb.Any
}func main() {// 創(chuàng)建 User 結構user := &User{Name: "Alice", Age: 25}// 將 User 結構封裝到 Any 里anyData, _ := anypb.New(user)// 創(chuàng)建 Response 并存儲 User 數(shù)據(jù)resp := &Response{Message: "User data",Data:    anyData,}// **序列化**data, _ := proto.Marshal(resp)// **反序列化**newResp := &Response{}proto.Unmarshal(data, newResp)// **解析 Any 字段**newUser := &User{}newResp.Data.UnmarshalTo(newUser)fmt.Println("Message:", newResp.Message)fmt.Println("User Name:", newUser.Name, "Age:", newUser.Age)
}

(3)Go 代碼解釋

  1. 封裝數(shù)據(jù):
    • 使用 anypb.New(user)User 結構轉換成 Any 類型。
  2. 序列化 Response
    • 使用 proto.Marshal(resp) 進行序列化,便于存儲或傳輸。
  3. 反序列化 Response
    • 使用 proto.Unmarshal(data, newResp) 解析 Response 結構。
  4. 解析 Any 數(shù)據(jù):
    • newResp.Data.UnmarshalTo(newUser) 解析 Any 字段,恢復 User 結構。

6. Protobuf 編碼原理

Protobuf 使用高效的二進制格式來存儲和傳輸數(shù)據(jù),其中最關鍵的編碼方式之一是 Varint(變長整數(shù)編碼)。它的核心思想是:

  • 數(shù)值越小,占用字節(jié)越少
  • 數(shù)值越大,占用字節(jié)越多
  • 高效存儲,減少帶寬消耗

6.1 什么是 Varint?

Varint(變長整數(shù)編碼) 是一種特殊的編碼方式,它可以使用 1 到 N 個字節(jié) 表示整數(shù)。

  • 小數(shù)占用更少字節(jié)(如 1 只需要 1 個字節(jié))。
  • 大數(shù)會自動擴展到多個字節(jié)(如 300 需要 2 個字節(jié))。

6.2 Varint 編碼規(guī)則

  1. 每個字節(jié)的最高位(MSB,Most Significant Bit)是“是否還有后續(xù)字節(jié)的標志”
    • 最高位為 0:表示這是最后一個字節(jié)。
    • 最高位為 1:表示后面還有字節(jié)。
  2. 剩下的 7 位存儲數(shù)據(jù)(低位優(yōu)先,LSB)。

6.3 具體示例

(1)數(shù)字 1 的 Varint 編碼

0000 0001  (只有 1 個字節(jié))
  • 最高位 0:表示這是最后一個字節(jié)。
  • 其余 7 位 000 0001(= 1)。

存儲方式:

[0000 0001]  → 1 字節(jié)

(2)數(shù)字 300 的 Varint 編碼

先看二進制表示:

300 = 100101100(9 位)

需要拆成 7 位 + 剩余部分

低 7 位: 0101100  → 0x2C(44)
高 2 位: 0000010  → 0x02(2)
  • 第一字節(jié):1010 1100(0xAC)
    • 最高位 1(表示后面還有字節(jié))。
    • 剩余 7 位存 010 1100(= 44)。
  • 第二字節(jié):0000 0010(0x02)
    • 最高位 0(表示這是最后一個字節(jié))。
    • 剩余 7 位存 000 0010(= 2)。

最終編碼

[1010 1100]  [0000 0010]  → 2 字節(jié)(0xAC 0x02)

6.4 Wire Type(數(shù)據(jù)類型編碼)

Protobuf 數(shù)據(jù)存儲為 鍵值對(key-value) 形式,每個字段的 key 也需要編碼。
字段的 key字段編號 + Wire Type 組成。

Wire Type作用
Varint0變長整數(shù)(int32, int64, bool, enum
Fixed64164 位定長(double, fixed64, sfixed64
Length-delimited2變長數(shù)據(jù)(string, bytes, message, repeated
Start group3已廢棄(用于嵌套數(shù)據(jù))
End group4已廢棄
Fixed32532 位定長(float, fixed32, sfixed32

存儲格式

[字段編號 << 3] | [Wire Type]  [數(shù)據(jù)]

字段編號左移 3 位,低 3 位存 Wire Type

6.5 例子:Protobuf 編碼解析

假設 Person 結構如下:

message Person {int32 id = 1;        // 1 字段編號string name = 2;     // 2 字段編號
}

數(shù)據(jù):

{"id": 150,"name": "Alice"
}

編碼過程

  1. 字段 id = 150

    • 字段編號 = 1
    • Wire Type = 0(Varint)
    • key = (1 << 3) | 0 = 0000 1000 (0x08)
    • 150 的 Varint 編碼:1001 0110 0000 0001(0x96 0x01)

    最終存儲

    [0x08]  [0x96 0x01]  (字段編號 1,Varint)
    
  2. 字段 name = "Alice"

    • 字段編號 = 2
    • Wire Type = 2(Length-delimited,字符串)
    • key = (2 << 3) | 2 = 0001 0001 (0x12)
    • "Alice" = 5 個字節(jié)(0x41 0x6C 0x69 0x63 0x65

    最終存儲

    [0x12]  [0x05]  [0x41 0x6C 0x69 0x63 0x65]
    

6.6 解析 Protobuf 二進制數(shù)據(jù)

假設收到如下二進制數(shù)據(jù):

08 96 01 12 05 41 6C 69 63 65

逐字節(jié)解析:

  1. 08 = 0000 1000(字段編號 1,Wire Type 0,Varint)
  2. 96 01 = 150(Varint 解碼)
  3. 12 = 0001 0010(字段編號 2,Wire Type 2,字符串)
  4. 05 = 長度 5
  5. 41 6C 69 63 65 = "Alice"

最終解析為:

{"id": 150,"name": "Alice"
}
http://www.risenshineclean.com/news/28949.html

相關文章:

  • 網站建設做什么百度收錄查詢工具
  • 互聯(lián)網 政府門戶網站建設方案最新國際新聞50條簡短
  • 網站后期維護費用邯鄲seo營銷
  • 做黃色網站怎么賺錢精準防控高效處置
  • 價格劃算的東莞建網站公司優(yōu)化營商環(huán)境評價
  • 東莞物流公司張家界seo
  • 江蘇 做網站推廣目標怎么寫
  • 國外電商網站如何做icp備案網頁seo是什么意思
  • 泵 品牌網站建設深圳網站建設系統(tǒng)
  • 情人節(jié)給女朋友做網站線上推廣軟件
  • 南京公司網站開發(fā)合肥瑤海區(qū)
  • 一個jsp做的購物小網站搜索引擎優(yōu)化的方法和技巧
  • wordpress文庫插件搜索引擎優(yōu)化的流程
  • wordpress裝在根目錄文件夾中_如何通過域名直接訪問?google關鍵詞seo
  • 四川省建筑設計院排名seo哪家公司好
  • 動態(tài)網站數(shù)據(jù)庫設計seo搜索引擎優(yōu)化排名哪家更專業(yè)
  • 在網上如何找做網站的人品牌營銷策略分析
  • 企業(yè)網站建設費用定金怎么做賬關鍵詞查網址
  • 昆山做網站哪家好百度競價排名廣告定價鮮花
  • 做網站用什么軟件知乎google瀏覽器下載
  • 企業(yè)做定制網站的好處自助建站免費建站平臺
  • 網站出現(xiàn)的的問題軟文營銷案例
  • 泰安網站制作seo海外
  • 做電池的外貿網站廣州日新增51萬人
  • 哪個網站不花錢可以做招聘互聯(lián)網營銷的特點
  • wordpress下載器插件廣東seo價格是多少錢
  • 網站建設 日志免費外鏈網
  • 做網站可以在哪兒接活app推廣拉新接單平臺
  • 梅州專業(yè)網站建設教程高端品牌網站建設
  • flash網站的優(yōu)勢廈門谷歌seo公司