01| 簡介 02| 安裝 2.1 Windows 下安裝 03| 簡單使用 3.1 編譯 3.2 Python 示例 3.3 C# 示例
01| 簡介
Protobuf(Protocol Buffers),是 Google 開發的一種跨語言、跨平臺的可擴展機制,用于序列化結構化數據。
與 XML 和 JSON 格式相比,protobuf 更小、更快、更便捷。protobuf 目前支持 C++、Java、Python、Objective-C,如果使用 proto3,還支持 C#、Ruby、Go、PHP、JavaScript 等語言。
官網地址:https://developers.google.cn/protocol-buffers/
GitHub 地址:https://github.com/protocolbuffers/protobuf
優點:
- 性能好
- 跨語言
缺點:
- 二進制格式可讀性差:為了提高性能,protobuf 采用了二進制格式進行編碼,這直接導致了可讀性差。
- 缺乏自描述:XML 是自描述的,而 protobuf 不是,不配合定義的結構體是看不出來什么作用的。
02| 安裝
2.1 Windows 下安裝
下載地址:https://github.com/protocolbuffers/protobuf/releases
下載 protoc-3.9.1-win64.zip,這個是編譯后的壓縮包,相當于綠色版,解壓后,將其下的 bin 目錄添加到環境變量就可以了,省去了安裝的麻煩。

然后打開命令提示符,輸入命令:
protoc
?--version
成功顯示版本號,則表示安裝成功。如下圖:

03| 簡單使用
3.1 編譯
使用 protobuf 首先需要定義 .proto 文件,先來看一個簡單的例子。
定義 Person.proto 文件,內容如下:
syntax
?=?
"proto3"
;
package
?Test;
message
?Person?{
??
string
?Name?=?
1
;
??
int32
?Age?=?
2
;
??
bool
?Marriage?=?
3
;
}
-
syntax = "proto3";
指定正在使用 proto3 語法,否則 protobuf 將默認使用的是 proto2。 -
package Test;
指定命名空間(C# 中)。 -
message
是關鍵字,定義結構化數據。 - 等號后面的數字是字段唯一編號( 注意不是字段的值 ),用于二進制格式消息中標識字段。
protoc 是 protobuf 自帶的編譯器 ,可以將 .proto 文件編譯成 java、python、go、C# 等多種語言的代碼,直接引用。
編譯命令:
protoc
?-I=E:\GL\Test2017?--python_out=E:\GL\Test2017?Person.proto
編譯命令說明:
- -I 表示源文件(.proto 文件)所在文件夾路徑。
- --python_out 表示目標語言為 python,且指定生成的 .py 文件存放目錄。相應的,C# 為 csharp_out,
- Person.proto 為源文件文件名,如果有多個,空格隔開。
3.2 Python 示例
安裝
protobuf
。
調用編譯命令編譯 Person.proto,編譯后生成文件:
Person_pb2.py
,添加至項目中,序列化和反序列化示例如下:
import
?Person_pb2
person?=?Person_pb2.Person()
person.Name?=?
'張三'
person.Age?=?
20
person.Marriage?=?
True
#?序列化
b?=?person.SerializeToString()
print(b)
#?反序列化
p?=?Person_pb2.Person()
p.ParseFromString(b)
print(
f'Name:?
{p.Name}
;?Age:?
{p.Age}
;?Marriage:?
{p.Marriage}
'
)
輸出:
b'\n\x06\xe5\xbc\xa0\xe4\xb8\x89\x10\x14\x18\x01'
Name:?張三;?Age:?
20
;?Marriage:?
True
注意,不能這樣寫,這是錯誤的:
p
?=?Person_pb2.Person().ParseFromString(b)
3.3 C# 示例
C# 下的 Protobuf 有 3 個版本:
- Google.ProtoBuf:Google官方版本,https://github.com/google/protobuf/tree/master/csharp
- protobuf-net:.net 社區版本,由 .net 社區愛好者開發,https://github.com/mgravell/protobuf-net
- Google.ProtocolBuffers:據說是由谷歌的 .net 員工在官方版本還未出來的時候開發的,https://github.com/jskeet/protobuf-csharp-port
這里我們介紹谷歌官方版本。
在 VS 中,通過 NuGet 安裝 'google.protobuf' 包。
using
?Google.Protobuf;
using
?System;
using
?Test;
namespace
?
Protobuf
{
????
class
?
Program
????{
????????
static
?
void
?
Main
(
string
[]?args
)
????????
{
????????????Person?person?=?
new
?Person();
????????????person.Name?=?
"張三"
;
????????????person.Age?=?
20
;
????????????person.Marriage?=?
true
;
????????????
//?序列化
????????????
byte
[]?buffer?=?person.ToByteArray();
????????????
foreach
?(
byte
?b?
in
?buffer)
????????????{
????????????????Console.Write(b.ToString(
"X2"
)?+?
"?"
);
????????????}
????????????Console.WriteLine();
????????????
//?反序列化
????????????Person?p?=?Person.Parser.ParseFrom(buffer);
????????????Console.WriteLine(
string
.Format(
"Name:?{0},?Age:?{1},?Marriage:?{2}"
,?p.Name,?p.Age,?p.Marriage));
????????????Console.Read();
????????}
????}
}
輸出:
0A?06?E5?BC?A0?E4?B8?89?10?14?18?01
Name:?張三,?Age:?20,?Marriage:?True
比較一下 Python 的輸出,好像不一樣,Python 中第一個字節是 \n,而這里是 0A。\n 在 ASCII 中的值就是 0A。所以兩種語言的序列化結果是一樣的。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
