一、protobuf簡介
Protocol Buffers (簡稱 protobuf) 是Google開源的一種輕便高效的序列化數據結構化方法,設計時考慮到可擴展性、效率和簡潔性。它可以用於數據存儲、通信協議等方面。protobuf支持C++、Java、Python、Go和其他多種編程語言。
比較常用的序列化方法有 JSON 和 XML,它們都需要大量的標籤和字符來描述數據,對於大量數據傳輸時,這些標籤和字符會帶來很多的數據冗餘和數據解析時間。protobuf 則採用二進制編碼方式來描述數據,並且允許壓縮數據,大大減少了傳輸數據量和解析數據的時間。
二、protobuf使用
protobuf 文件是一種純文本文件,它定義了 protobuf 協議,即定義了數據結構和數據格式。
1.定義數據結構
下面是一個簡單的 protobuf 定義文件的例子:
syntax = "proto3";
message Person {
string name = 1;
int32 id = 2;
repeated string email = 3;
}
其中,message是protobuf關鍵字,符合C語言的結構體定義,定義了一個名為Person的結構體,包含三個字段:name(類型為字符串)、id(類型為整型)、email(類型為字符串數組)。
注意:每個字段都必須有唯一的數字標識符(1,2,3)並指定字段類型。
2.生成代碼
生成代碼的方式分為兩種:靜態代碼生成和動態代碼生成。
靜態代碼生成
使用protobuf靜態代碼生成器生成代碼會加快編譯速度,避免大多數錯誤,並且可以在編譯時捕獲協議文件錯誤。下面介紹使用protobuf靜態代碼生成器如何生成不同語言的代碼。
(1) C++
通過以下命令生成C++代碼:
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
其中,$SRC_DIR 是 protobuf 定義文件所在的目錄,$DST_DIR 為生成 C++ 代碼目錄,addressbook.proto 是 protobuf 定義文件的文件名。
(2) Java
通過以下命令生成 Java 代碼:
protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto
其中,$SRC_DIR 是 protobuf 定義文件所在的目錄,$DST_DIR 為生成 Java 代碼目錄,addressbook.proto 是 protobuf 定義文件的文件名。
動態代碼生成
使用動態代碼生成可以避免生成代碼,但也會有一些缺點,如在解析協議時降低了效率。
例如,在 Python 中,使用以下代碼解析 protobuf 數據:
import protobuf
from google.protobuf.json_format import MessageToDict
proto_file = open('./addressbook.proto', 'rb').read()
address_book = protobuf.json_format.Parse(proto_file, protobuf.AddressBook())
# 將 proto message 轉為 dict
address_book_dict = MessageToDict(address_book)
三、protobuf的應用
1.網絡傳輸數據
protobuf 可以直接用於網絡通信,它可以大幅度減少數據傳輸時間和網絡帶寬。下面是一個使用 Python 發送 protobuf 數據的例子:
import socket
import protobuf
def send_data(host, port, data):
# 連接服務器
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((host, port))
# 將數據序列化為二進制格式字節流
serialized_data = data.SerializeToString()
# 發送數據
sock.sendall(serialized_data)
print('Data sent successfully')
2.存儲數據
protobuf 可以將數據序列化為二進制格式,以便保存到文件或數據庫中。下面是一個使用 Python 將數據存入文件的例子:
import protobuf
def write_to_file(file_path, data):
# 將數據序列化為二進制格式字節流
serialized_data = data.SerializeToString()
# 保存數據到文件
with open(file_path, 'wb') as f:
f.write(serialized_data)
print('Data saved successfully')
四、總結
如上所述,protobuf 可以大大減少數據傳輸時間和網絡帶寬,提高了數據傳輸效率,同時也可以用於存儲數據。同時,protobuf 還可以提高編程效率,抽象了底層數據格式的處理方式。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/279459.html