有研究表明,一條消息數據,用protobuf序列化後的大小是json的10分之一,xml格式的20分之一,是二進制序列化的10分之一,ProtoBuf的優勢還是很明顯的。這裏簡單介紹哈使用
一、下載protobuf
https://github.com/google/protobuf/releases
二、編寫proto原文件
syntax = "proto3";//標明proto版本
package protobuf;//包名
//一個message相當於一個類
//1,2,3不代表參數默認值,而是參數標籤
//repeated 可以理解爲數組
message StoreRequest {
string name = 1;
int32 num = 2;
int32 result = 3;
repeated string myList=4;
}
(1)版本號
對於一個pb文件而言,文件首個非空、非註釋的行必須註明pb的版本,即syntax = "proto3";
,否則默認版本是proto2。
(2)Message
一個message類型看上去很像一個Java class,由多個字段組成。每一個字段都由類型、名稱組成,位於等號右邊的值不是字段默認值,而是數字標籤,可以理解爲字段身份的標識符,類似於數據庫中的主鍵,不可重複,標識符用於在編譯後的二進制消息格式中對字段進行識別,一旦你的pb消息投入使用,字段的標識就不應該再改變。數字標籤的範圍是[1, 536870911],其中19000~19999是保留數字。
(3)類型
每個字段的類型(int32
,string
)都是scalar的類型,和其他語言類型的對比如下:
(4)修飾符
如果一個字段被repeated
修飾,則表示它 是一個列表類型的字段,比如上面
repeated string myList=3;
等於是List<string> myList
如果你希望可以預留一些數字標籤或者字段可以使用reserved修飾符:
message Login {
reserved 2, 15, 9 to 11;
reserved "lg", "bo";
string bo = 3; // 編譯報錯,因爲‘bo’已經被標爲保留字段
}
(5)默認值
- string類型的默認值是空字符串
- bytes類型的默認值是空字節
- bool類型的默認值是false
- 數字類型的默認值是0
- enum類型的默認值是第一個定義的枚舉值
- message類型(對象,如上文的SearchRequest就是message類型)的默認值與語言相關
- repeated修飾的字段默認值是空列表。
注:如果一個字段的值等於默認值(如bool類型的字段設爲false),那麼它將不會被序列化,這樣的設計是爲了節省流量
(6)枚舉
每個枚舉值有對應的數值,數值不一定是連續的。第一個枚舉值的數值必須是0且至少有一個枚舉值,否則編譯報錯。編譯後編譯器會爲你生成對應語言的枚舉類。
message StoreRequest {
string name = 1;
int32 number = 2;
int32 result = 3;
enum CoinType
{
None=0;
CT_cny = 1;
CT_usd = 2;
CT_hkd = 3;
CT_jpy = 4;
CT_eur = 5;
}
CoinType coin = 4;
}
可以使用MessageType.EnumType
的形式引用定義在其它message類型中的枚舉。
注:由於編碼原因,出於效率考慮,官方不推薦使用負數作爲枚舉值的數值。
(7)Maps
pb中也可以使用map類型(官方並不認爲是一種類型,此處稱之爲類型僅便於理解),絕大多數scalar類型都可以作爲key,除了浮點型和bytes,枚舉型也不能作爲key,value可以是除了map以外的任意類型:
map<string, object> obj = 3;
map其實是一種語法糖,它等價於以下形式:
message MapField {
key_type key = 1;
value_type value = 2;
}
repeated MapField map_field = N;
注:map
類型字段不支持repeated
,value的順序是不定的。
(8)包
你可以用指定package
以避免類型命名衝突:
package store.ba;
message Buy{...}
然後可以用類型的全限定名來引用它:
message Store{
...
store.ba.Buy buy=1;
..
}
指定包名後,會對生成的代碼產生影響,生成的類會以你指定的package
作爲包名。
這裏不再做詳細介紹,可以參照https://developers.google.com/protocol-buffers/docs/encoding?hl=zh-cn
三、配置環境變量
將解壓出來的protoc.exe放在一全英文路徑下,並把其路徑名放在windows環境變量下的path下。
(1)以win7爲例,右鍵我的電腦->屬性->高級系統設置->環境變量->系統變量->雙擊修改 變量”path” ,添加protoc.exe的路徑,即:
;E:\protoc-3.6.0-win32\bin
(2)打開cmd 執行
protoc --version
顯示libprotoc 3.6.0即配置完畢
四、win+R打開cmd窗口執行以下命令
E:\protoc-3.6.0-win32\bin\protoc.exe -I=e:\protoc-3.6.0-win32\bin --csharp_out=e:\protoc-3.6.0-win32\bin e:\protoc-3.6.0-win32\bin\msg.proto
若配置了環境變量:
protoc -I=e:\protoc-3.6.0-win32\bin --csharp_out=e:\protoc-3.6.0-win32\bin e:\protoc-3.6.0-win32\bin\msg.proto
protoc -I=源地址 --csharp_out=目標地址 源地址/xxx.proto
五、然後就看到目標路徑生成了Msg.cs
(未完待續)