Protobuf序列化这么强,为什么不花五分钟学习一下呢?

开发 后端
java自带的序列化机制效率太低,有很多缺点。因此涌现出了很多优秀的系列化框架,比如说protobuf、protostuff、thrift、hession、kryo、avro、fst、msgpack等等。

[[386741]]

 java自带的序列化机制效率太低,有很多缺点。因此涌现出了很多优秀的系列化框架,比如说protobuf、protostuff、thrift、hession、kryo、avro、fst、msgpack等等。这篇文章我们就看一下protobuf,给出一个简单案例,看看其是如何实现的。

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

一、为什么要使用protobuf?

使用protobuf的原因肯定是为了解决开发中的一些问题,那使用其他的序列化机制会出现什么问题呢?

(1)java默认序列化机制:效率极低,而且还能不能跨语言之间共享数据。

(2)XML常用于与其他项目之间数据传输或者是共享数据,但是编码和解码会造成很大的性能损失。

(3)json格式也是常见的一种,但是在json在解析的时候非常耗时,而且json结构非常占内存。

但是我们protobuf是一种灵活的、高效的、自动化的序列化机制,可以有效的解决上面的问题。

二、如何使用protobuf

protobuf这么优秀使用起来也是非常的简单,我们可以给出其主要的三个步骤,然后使用一个基本的案例去实现一下。

(1)定义.proto文件:我们在这个文件中描述我们序列化的信息,类似于bean类。

(2)根据.proto生成对应的类文件,上面这个proto就像是一个模板,现在我们要根据这个模板创建出一个java类。

(3)序列化。

有了这个基本的步骤我们我们就具体去实现一下:

1、下载安装protobuf

第一步:下载解压

我的电脑是windows10,因此这里给出在windows下的使用,linux下面使用我也将在后续文章推出。我们首先下载protobuf(github上搜索protobuf,有各种语言可供选择)。选择protoc-3.9.0-win64.zip。下载完成之后解压到D:/protobuf目录下面就好了。

第二步:配置环境变量

也就是将D:\protobuf\protoc-3.9.0-win64\bin配置到path环境变量里面。

第三步:验证是否安装成功

最后我们可以在cmd中输入protoc --version验证一下,是否成功。

OK,到这里我们就安装好了。

2、编写proto文件

之前我们说过proto 文件非常类似java的bean。在这里我们在bin目录下新建一个Person.proto文件(和proto.exe)。输入下列内容:

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

我们解释一些我们都写了什么

(1)第一行有一个proto3,他表示的是protobuf的语法版本,就类似于jdk1.7和jdk1.8的概念。需要在第一行指定。默认使用的是proto2。

(2)java_package:表示的是java包,不指定就使用 package.生成的类会放到该package下。这里表示把生成的类存放在com.fdd.protobuf包下面。

(3)java_outer_classname:我们说过.proto文件,要生成对应的类,这个参数就指定输出什么类名。这里表示生成的类名是PersonProto。

(4)message 是用于数据格式定义.

  • 一个 .proto 文件中可以定义多个 message
  • message 中定义的字段支持 string、byte、bool、map、enum、数字类型和用户自定义的 message
  • 定义字段后面需要指定唯一的标识数字,这些数字用于识别二进制格式 message 中的字段,一旦开始使用这个 message,那么标识数字就不能改变
  • 如果需要定义 List,则在字段前加repeated即可.
  • 如果已经使用过该 message 生成的类后,想要增加字段直接新增即可.当新增字段的类解析老数据时,会将新字段置为默认值.当旧的类解析新数据时会忽视掉新增字段.

比如说这里我们就定义一个复杂的proto文件:

  1. syntax = "proto3"
  2. option java_package = "com.fdd.protobuf"
  3. option java_outer_classname = "Persons"
  4. message Staff { 
  5.     int32 id = 1; 
  6.     string name = 2; 
  7.     int32 age = 3; 
  8.     // 枚举示例 
  9.     enum PhoneType { 
  10.         MOBILE = 0; 
  11.         TELEPHONE = 1; 
  12.     } 
  13.     // 嵌套示例 
  14.     message PhoneNumber { 
  15.         string number = 1; 
  16.         PhoneType type = 2; 
  17.  
  18.     }  
  19.     // list示例 
  20.     repeated PhoneNumber phone = 4;       
  21.     message Map { 
  22.         string key = 1; 
  23.         int32 value = 2; 
  24.     } 
  25.     // map示例 
  26.     Map map = 5; 

由于这里只是展示一个基本案例,对于其他的数据类型可以根据自己的需要定义即可。

3、根据proto文件生成class类文件

编译起来很简单,在我们下载好的protobuf下面有一个bin目录,里面有一个proto.exe。我们就使用这个去编译person.proto文件就好。

也就是执行proto.exe --java_out = / Person.proto就会编译成功。

4、使用class类文件

上面意味着我们已经做好了序列化的准备工作,接下来我们就可以直接使用这个类了。

(1)第一步:将生成的PersonProto类引入到我们的IDEA或者是eclipse中。

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

  1. <dependency> 
  2.     <groupId>com.google.protobuf</groupId> 
  3.     <artifactId>protobuf-java</artifactId> 
  4.     <version>3.9.0</version> 
  5. </dependency> 

(3)第三步:使用

首先看一些如何序列化:

  1. //1、 创建Builder 
  2. PersonProto.Person.Builder builder = PersonProto.Person.newBuilder(); 
  3. //2、 设置Person的属性 
  4. builder.setAge(20); 
  5. builder.setName("java的架构师技术栈"); 
  6. //3、 创建Person 
  7. PersonProto.Person person = builder.build(); 
  8. //4、序列化 
  9. byte[] data = person.toByteArray(); 
  10. //5、将data保存在本地或者是传到网络 

然后反序列化

 

  1. try { 
  2.        //一行代码实现反序列化,data可以是本地数据或者是网络数据 
  3.        PersonProto.Person person = PersonProto.Person.parseFrom(data); 
  4.        System.out.println(person.getAge()); 
  5.        System.out.println(person.getName()); 
  6. } catch (InvalidProtocolBufferException e) { 
  7.        e.printStackTrace(); 

OK,基本的使用流程就是这。

总结

基本上就是我们定义好proto文件,然后使用proto.exe编译成类文件,最后导入这个类和依赖就可以直接使用了。当然这只是一个最简单不过的代码,可以把这篇教程当成一个简单的使用教程。

本文转载自微信公众号「愚公要移山」,作者冯冬冬。转载本文请联系愚公要移山公众号。

 

责任编辑:武晓燕 来源: 愚公要移山
相关推荐

2021-01-26 05:39:57

Protobuf java

2011-06-01 15:18:43

Serializabl

2019-10-24 08:11:19

IP下一跳静态路由

2023-07-02 16:34:06

GPU虚拟化深度学习

2024-09-03 08:17:59

2009-11-16 10:53:30

Oracle Hint

2020-06-16 08:47:53

磁盘

2019-07-09 14:42:17

SQLexplain索引

2023-07-12 15:50:29

机器学习人工智能

2022-03-18 15:41:29

原子化服务HarmonyOS鸿蒙

2020-03-06 10:45:48

机器学习人工智能神经网络

2016-07-08 14:26:55

云计算

2009-11-02 18:07:58

Oracle数据库

2019-08-09 10:33:36

开发技能代码

2009-10-22 16:18:19

Oracle表空间

2024-09-18 08:21:24

JavaScriptTypeScriptprototype

2009-11-05 14:53:54

Visual Stud

2021-06-07 09:51:22

原型模式序列化

2021-10-19 07:27:08

HTTP代理网络

2017-10-10 05:05:33

KerasRNN序列学习
点赞
收藏

51CTO技术栈公众号