溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何使用Protobuf序列化

發(fā)布時(shí)間:2021-10-18 09:50:11 來源:億速云 閱讀:122 作者:柒染 欄目:編程語言

這篇文章給大家介紹如何使用Protobuf序列化,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

java自帶的序列化機(jī)制效率太低,有很多缺點(diǎn)。因此涌現(xiàn)出了很多優(yōu)秀的系列化框架,比如說protobuf、protostuff、thrift、hession、kryo、avro、fst、msgpack等等。這篇文章我們就看一下protobuf,給出一個(gè)簡(jiǎn)單案例,看看其是如何實(shí)現(xiàn)的。

注:若你對(duì)序列化概念和基本使用還有疑惑,可以翻看我之前的文章,或者百度一些基本概念和作用。

一、為什么要使用protobuf?

使用protobuf的原因肯定是為了解決開發(fā)中的一些問題,那使用其他的序列化機(jī)制會(huì)出現(xiàn)什么問題呢?

(1)java默認(rèn)序列化機(jī)制:效率極低,而且還能不能跨語言之間共享數(shù)據(jù)。

(2)XML常用于與其他項(xiàng)目之間數(shù)據(jù)傳輸或者是共享數(shù)據(jù),但是編碼和解碼會(huì)造成很大的性能損失。

(3)json格式也是常見的一種,但是在json在解析的時(shí)候非常耗時(shí),而且json結(jié)構(gòu)非常占內(nèi)存。

但是我們protobuf是一種靈活的、高效的、自動(dòng)化的序列化機(jī)制,可以有效的解決上面的問題。

二、如何使用protobuf

protobuf這么優(yōu)秀使用起來也是非常的簡(jiǎn)單,我們可以給出其主要的三個(gè)步驟,然后使用一個(gè)基本的案例去實(shí)現(xiàn)一下。

(1)定義.proto文件:我們?cè)谶@個(gè)文件中描述我們序列化的信息,類似于bean類。

(2)根據(jù).proto生成對(duì)應(yīng)的類文件,上面這個(gè)proto就像是一個(gè)模板,現(xiàn)在我們要根據(jù)這個(gè)模板創(chuàng)建出一個(gè)java類。

(3)序列化。

有了這個(gè)基本的步驟我們我們就具體去實(shí)現(xiàn)一下:

1、下載安裝protobuf

第一步:下載解壓

我的電腦是windows10,因此這里給出在windows下的使用,linux下面使用我也將在后續(xù)文章推出。我們首先下載protobuf(github上搜索protobuf,有各種語言可供選擇)。選擇protoc-3.9.0-win64.zip。下載完成之后解壓到D:/protobuf目錄下面就好了。

第二步:配置環(huán)境變量

也就是將D:\protobuf\protoc-3.9.0-win64\bin配置到path環(huán)境變量里面。

第三步:驗(yàn)證是否安裝成功

最后我們可以在cmd中輸入protoc --version驗(yàn)證一下,是否成功。

OK,到這里我們就安裝好了。

2、編寫proto文件

之前我們說過proto  文件非常類似java的bean。在這里我們?cè)赽in目錄下新建一個(gè)Person.proto文件(和proto.exe)。輸入下列內(nèi)容:

syntax="proto3";  option java_package = "com.fdd.protobuf";    option java_outer_classname = "PersonProto";    message Person  {    string name = 1;   int32 age = 2; }

我們解釋一些我們都寫了什么

(1)第一行有一個(gè)proto3,他表示的是protobuf的語法版本,就類似于jdk1.7和jdk1.8的概念。需要在第一行指定。默認(rèn)使用的是proto2。

(2)java_package:表示的是java包,不指定就使用  package.生成的類會(huì)放到該package下。這里表示把生成的類存放在com.fdd.protobuf包下面。

(3)java_outer_classname:我們說過.proto文件,要生成對(duì)應(yīng)的類,這個(gè)參數(shù)就指定輸出什么類名。這里表示生成的類名是PersonProto。

(4)message 是用于數(shù)據(jù)格式定義.

  • 一個(gè) .proto 文件中可以定義多個(gè) message

  • message 中定義的字段支持 string、byte、bool、map、enum、數(shù)字類型和用戶自定義的 message

  • 定義字段后面需要指定唯一的標(biāo)識(shí)數(shù)字,這些數(shù)字用于識(shí)別二進(jìn)制格式 message 中的字段,一旦開始使用這個(gè) message,那么標(biāo)識(shí)數(shù)字就不能改變

  • 如果需要定義 List,則在字段前加repeated即可.

  • 如果已經(jīng)使用過該 message  生成的類后,想要增加字段直接新增即可.當(dāng)新增字段的類解析老數(shù)據(jù)時(shí),會(huì)將新字段置為默認(rèn)值.當(dāng)舊的類解析新數(shù)據(jù)時(shí)會(huì)忽視掉新增字段.

比如說這里我們就定義一個(gè)復(fù)雜的proto文件:

syntax = "proto3"; option java_package = "com.fdd.protobuf"; option java_outer_classname = "Persons"; message Staff {     int32 id = 1;     string name = 2;     int32 age = 3;     // 枚舉示例     enum PhoneType {         MOBILE = 0;         TELEPHONE = 1;     }     // 嵌套示例     message PhoneNumber {         string number = 1;         PhoneType type = 2;      }      // list示例     repeated PhoneNumber phone = 4;           message Map {         string key = 1;         int32 value = 2;     }     // map示例     Map map = 5; }

由于這里只是展示一個(gè)基本案例,對(duì)于其他的數(shù)據(jù)類型可以根據(jù)自己的需要定義即可。

3、根據(jù)proto文件生成class類文件

編譯起來很簡(jiǎn)單,在我們下載好的protobuf下面有一個(gè)bin目錄,里面有一個(gè)proto.exe。我們就使用這個(gè)去編譯person.proto文件就好。

也就是執(zhí)行proto.exe --java_out = / Person.proto就會(huì)編譯成功。

4、使用class類文件

上面意味著我們已經(jīng)做好了序列化的準(zhǔn)備工作,接下來我們就可以直接使用這個(gè)類了。

(1)第一步:將生成的PersonProto類引入到我們的IDEA或者是eclipse中。

(2)第二步:在idea或者是eclipse添加protobuf的依賴。

<dependency>     <groupId>com.google.protobuf</groupId>     <artifactId>protobuf-java</artifactId>     <version>3.9.0</version> </dependency>

(3)第三步:使用

首先看一些如何序列化:

//1、 創(chuàng)建Builder PersonProto.Person.Builder builder = PersonProto.Person.newBuilder(); //2、 設(shè)置Person的屬性 builder.setAge(20); builder.setName("java的架構(gòu)師技術(shù)棧"); //3、 創(chuàng)建Person PersonProto.Person person = builder.build(); //4、序列化 byte[] data = person.toByteArray(); //5、將data保存在本地或者是傳到網(wǎng)絡(luò)

然后反序列化

try {        //一行代碼實(shí)現(xiàn)反序列化,data可以是本地?cái)?shù)據(jù)或者是網(wǎng)絡(luò)數(shù)據(jù)        PersonProto.Person person = PersonProto.Person.parseFrom(data);        System.out.println(person.getAge());        System.out.println(person.getName()); } catch (InvalidProtocolBufferException e) {        e.printStackTrace(); }

關(guān)于如何使用Protobuf序列化就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI