前言
????????這一系列文章主要是對protobuf這種編碼格式的使用方式、特點、使用技巧進行說明,并在原生protobuf的基礎(chǔ)上進行擴展和優(yōu)化,使得它能更好地為我們服務(wù)
什么是protobuf
????????protobuf是由google推出一種數(shù)據(jù)編碼格式,不依賴平臺和語言,類似于xml和json。然而與xml和json最大的不同之處在于,protobuf并非是一種可以完全自解釋的編碼格式,這點在之后會有說明
為什么要使用protobuf
同樣作為一種編碼方式,protobuf的解析速度更快,編碼后的字節(jié)數(shù)更少。
其中解析速度的相關(guān)比較可以參看相關(guān)文章,這并不是本系列關(guān)心的重點,而字節(jié)數(shù)的減少將會是后續(xù)擴展和優(yōu)化的重點
比json和xml更便利的是,開發(fā)者只需要編寫一份.proto的描述文件,就可以通過google提供的編譯器生成不同平臺的模型代碼,包括java、C#等等,而不需要手動進行模型編寫
后續(xù)的示例都是采用java進行展示
基本的使用方式
首先,不同于使用某種具體的編程語言,模型文件是以.proto的描述文件形式進行定義的,在此文件中標識了模型的名字、字段類型、字段名字等、字段順序(這個屬性對于protobuf及其重要,會在下一篇原理中詳細描述)等
例如下面這個例子:
syntax = "proto3";
package tutorial;
option java_package = "cn.tera.protobuf.model";
option java_outer_classname = "AddressBookProtos";
message Person {
? required string name = 1;
? required int32 id = 2;
? string email = 3;
? enum PhoneType {
? ? MOBILE = 0;
? ? HOME = 1;
? ? WORK = 2;
? }
? message PhoneNumber {
? ? required string number = 1;
? ? PhoneType type = 2 [default = HOME];
? }
? repeated PhoneNumber phones = 4;
}
message AddressBook {
? repeated Person people = 1;
}
第一行定義的是語法,現(xiàn)在有proto3和proto2兩種版本,如果不定義,則默認proto2,后續(xù)的描述都以proto3版本為主
package是用來區(qū)分命名空間的,如果生成的是java,也會被默認成java的package,當然可以通過java_package另外指定。
如果指定了java_outer_classname,則生成的java文件的類名將會以此為準,且該文件中定義的所有類都會在被包含在該類之內(nèi)
在Person內(nèi)定義了模型的名字,之后是字段的類型、名稱、順序
required表示必須字段,在編碼和解碼時,該字段必須有值,否則就會失敗(不建議使用)
optional表示可選字段,在proto3的語法中可以省略
repeated表示可重復(fù)字段,對應(yīng)于java中的List或者array
編譯文件
編譯器下載地址
https://github.com/protocolbuffers/protobuf/releases/tag/v3.12.1
之后執(zhí)行命令
/Users/tianjiyuan/Documents/protobuf/protoc -I=/Users/tianjiyuan/Documents/blogs/protobuf/proto --java_out=/Users/tianjiyuan/Documents/blogs/protobuf/src/main/java/ /Users/tianjiyuan/Documents/blogs/protobuf/proto/AddressBookProtos.proto
注意,對于生成的java模型,編譯器會自動生成在.proto文件中定義的java_package文件夾,所以--java_out參數(shù)可以直接指定到項目的java source目錄,生成出的.java文件就會直接位于項目中了,十分方便
其中ProtobufTest.basicUse展示了protobuf的基本使用方法
proto文件夾中是所有后面會用到的.proto文件
protobuf和json的互相轉(zhuǎn)換
因為現(xiàn)在json格式的數(shù)據(jù)交互相對比較主流,因此當我們考慮使用protobuf時,需要考慮的第一個問題就是protobuf能否方便地和json進行格式轉(zhuǎn)換。答案是肯定的。
maven依賴
<dependency>
? ? ? ?<groupId>com.google.protobuf</groupId>
? ? ? ?<artifactId>protobuf-java-util</artifactId>
? ? ? ?<version>3.9.1</version>
?</dependency>
demo中的ProtobufTest.jsonToProtobuf展示了protobuf與json互相轉(zhuǎn)換