场景

ProtoBuf简介

protocol buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。

Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。

你可以定义数据的结构,然后使用特殊生成的源代码轻松的在各种数据流中使用各种语言进行编写和读取结构数据。你甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序。

ProtocolBuffer拥有多项比XML更高级的串行化结构数据的特性,ProtocolBuffer:

·        更简单

·        小3-10倍

·        快20-100倍

·        更少的歧义

·        可以方便的生成数据存取类

怎样使用ProtoBuf

定义proto描述文件

首先需要在一个 .proto 文件中定义你需要做串行化的数据结构信息。每个ProtocolBuffer信息是一小段逻辑记录,包含一系列的键值对。这里有个非常简单的 .proto 文件定义了个人信息:

message Person {required string name=1;required int32 id=2;optional string email=3;enum PhoneType {MOBILE=0;HOME=1;WORK=2;}message PhoneNumber {required string number=1;optional PhoneType type=2 [default=HOME];}repeated PhoneNumber phone=4;
}

当然这里的protobuf的秒数文件.proto也是有版本语法限制的,比如protoBuf3中没有required和optional。

每个消息类型拥有一个或多个特定的数字字段,每个字段拥有一个名字和一个值类型。值类型可以是数字(整数或浮点)、布 尔型、字符串、原始字节或者其他ProtocolBuffer类型,还允许数据结构的分级。

上面的message就类似于类,下面是属性。

required在protobuf2代表是必填的,optional在protobuf2中代表是可选的。repeated代表重复字段,类似于list。

下面的enum代表是枚举。

下面的message是在上面Person的里面,代表内部类。default代表默认值。

需要注意的是这里的=1,=2等都不是对其进行赋值,而是对属性做一个唯一标志。

编译描述文件

一旦你定义了自己的报文格式(message),你就可以运行ProtocolBuffer编译器,将你的 .proto 文件编译成特定语言的类。这些类提供了简单的方法访问每个字段(像是 query() 和set_query()),像是访问类的方法一样将结构串行化或反串行化。

编译器下载地址:

https://github.com/protocolbuffers/protobuf/releases

选择指定的操作系统的指定protobuf版本的protoc编译器进行下载

这里操作系统是Windows64位并且在下面要使用的protobuf的版本是3.13

所以这里下载对应的版本

将其下载到电脑上某路径下解压

后续就可以使用protoc.exe对proto文件进行编译。

为了使用方便,这里将protoc.exe添加进环境变量

然后打开cmd,输入protoc后回车,会输出编译的提示命令则是成功

Java中使用ProtoBuf序列化和反序列化示例

新建项目并引入依赖

打开IDEA-新建一个gradle项目,当然你也可以新建一个Maven项目。

这里以使用gradle作为依赖管理进行示例。

新建gradle项目后选择Java语言,然后添加protobuf相关的依赖。

来到Maven的中央仓库

https://mvnrepository.com/

搜索protobuf

这两个就是需要引入的依赖。

分别进入两个依赖中选择跟上面的编译的版本一致的版本

这里是Gradle的依赖,你也可以使用Maven并复制Maven的依赖。

找到IDEA中新建的gradle项目的build.gradle将两个依赖添加进去。

dependencies {compile ([group:'com.google.protobuf', name: 'protobuf-java', version: '3.13.0'],[group:'com.google.protobuf', name: 'protobuf-java-util', version: '3.13.0'])
}

因为设置了自动导入,所以会在项目中引入Google的相关protobuf的依赖的jar包

编写proto描述文件

然后在src下新建protobuf目录,在此目录下新建文件Student.proto

此时IDEA会提示,选择Text即可。

syntax = "proto3";package com.badao.protobuf;option optimize_for =SPEED;
option java_package = "com.badao.protobuf";
option java_outer_classname = "DataInfo";message Student {string name = 1;int32 age = 2;string address = 3;
}

然后将其内容修改如下

这里的syntax代表使用的语法规则是protobuf3

然后下面的package是缺省时的包名,如果下面没有设置java_package则会使用此设置,如果设置了则不会使用。

下面的是一些配置

optimize_for是文件级别的选项,Protocol Buffer定义三种优化级别SPEED/CODE_SIZE/LITE_RUNTIME。缺省情况下是SPEED。

SPEED: 表示生成的代码运行效率高,但是由此生成的代码编译后会占用更多的空间。

然后java_package就是配置的生成代码的包名,

java_outer_classname选项表明想要生成Java类的名称。如果在.proto文件中没有明确的java_outer_classname定义,生成的class名称将会根据.proto文件的名称采用驼峰式的命名方式进行生成。如(foo_bar.proto生成的java类名为FooBar.java)。

这里配置的类名就叫DataInfo。

编译描述文件生成代码

在IDEA中下面的Terminal新建一个终端

因为已经将protoc编译命令的exe添加进环境变量,所以这里直接使用protoc命令即可。

protoc --java_out=src/main/java src/protobuf/Student.proto

这里--java_out=src/main/java就是设置的要生成代码后存放的位置

后面跟着个空格然后跟的是 proto描述文件的位置

回车后如果没有报错,并且已经在src/main/java/com/badao/protobuf下生成DataInfo类

则编译成功。

对象数据的序列化与反序列化

在此包下新建一个ProtobuTest类,并编写main方法

package com.badao.protobuf;import com.google.protobuf.InvalidProtocolBufferException;public class ProtobufTest {public static void main(String[] args) throws InvalidProtocolBufferException {DataInfo.Student student = DataInfo.Student.newBuilder().setName("公众号:霸道的程序猿").setAge(100).setAddress("中国").build();byte[] bytes = student.toByteArray();DataInfo.Student student1 = DataInfo.Student.parseFrom(bytes);System.out.println(student1.getName());System.out.println(student1.getAge());System.out.println(student1.getAddress());}
}

注意这里的新建对象并对属性进行赋值时必须采用如上这种方式

        DataInfo.Student student = DataInfo.Student.newBuilder().setName("公众号:霸道的程序猿").setAge(100).setAddress("中国").build();

然后将对象进行序列化为字节数组就可以通过

byte[] bytes = student.toByteArray();

将字节数据反序列化为对象就可以通过

DataInfo.Student student1 = DataInfo.Student.parseFrom(bytes);

然后运行该main方法。

示例代码下载

https://download.csdn.net/download/BADAO_LIUMANG_QIZHI/12858952

ProtoBuf的介绍以及在Java中使用protobuf将对象进行序列化与反序列化相关推荐

  1. java图片序列化_Java中的强大武器——对象的序列化

    原标题:Java中的强大武器--对象的序列化 所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象.这个过程也可以通过网络实现,可以先在Windows机器上创建一个对象, ...

  2. java反序列化多个对象_java 序列化与反序列化多个对象 抛出异常

    jdk 1.8 IEDA 设置可以追加写入后,向目标文件序列化多个同一对象,再序列化出来时,因为反序列化时头部信息只读取一次,报出异常. 请问该怎么解决?或者代码写的有问题? import java. ...

  3. java培训教程分享:Java中怎样将数据对象序列化和反序列化?

    本期为大家介绍的java培训教程是关于"Java中怎样将数据对象序列化和反序列化?"的内容,相信大家都知道,程序在运行过程中,可能需要将一些数据永久地保存到磁盘上,而数据在Java ...

  4. Java中枚举的线程安全性及序列化问题

    转载自  Java中枚举的线程安全性及序列化问题 Java SE5提供了一种新的类型-Java的枚举类型,关键字enum可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序 ...

  5. java中的类和对象(重点)超详细

    java中的类和对象 1.类与对象的初步认知 2.类和对象的实例化 3.类的成员 3.1.字段,属性,成员变量 3.2.方法 3.3.static 关键字 3.4.小结 4.封装 4.1.privat ...

  6. Java中,一切皆是对象——java中的对象类型与基本数据类型的区别

    起因:取一个list给另一个list赋值,然后在另一个list中取出进行修改.list其中类型为对象时,String时,基本数据类型时. [java中的对象类型与基本数据类型的区别] #声明和实例化 ...

  7. java中的equals()空对象的出错

    java中的equals()空对象的出错: String a = "abc"; //不是空对象boolean b = a.equals("abc"); //不会 ...

  8. java中对象的序列化和反序列化

    [对象的序列化和反序列化 ] 1.定义: 序列化--将对象写到一个输出流中.反序列化则是从一个输入流中读取一个对象.类中的成员必须是可序列化的,而且要实现Serializable接口,这样的类的对象才 ...

  9. 12月29日--Java中有关类与对象的学习记录

    1.12月29日第一课记录 Java中有关类与对象的学习记录 一.基本概念部分 1.类:具有相同.相似的属性.特征.行为方式以及功能的一类事物的总称 (举例:一类用户,如淘宝用户) 类是对象的模板 是 ...

最新文章

  1. 汇总pandas中dataframe的删除操作
  2. python判断路径是文件还是文件夹_python之判断是否是目录或文件
  3. 如何在 Kaggle 首战中进入前 10%
  4. 使用java spring开发ckeditor的文件上传功能(转)
  5. linux虚拟服务器新增磁盘怎么挂载,如何在vmware虚拟机Linux中增加硬盘的方法(教程)...
  6. 爬虫基本库request使用—爬取猫眼电影信息
  7. Qt文档阅读笔记-Qt跨平台库(Qt基本库)
  8. [CQOI2014]数三角形 题解(找规律乱搞)
  9. 电池成本涨幅“离谱” 新能源车企涨声一片
  10. css 毛玻璃_css揭秘-视觉效果
  11. lduan SCVMM 2012 库服务器(五)
  12. 波形捕捉:(3)捕捉设备性能
  13. atitit.软件gui按钮and面板---os区-----软链接,快捷方式
  14. 中公教育python培训讲师面试题_中公教育面试经验
  15. LEACH路由协议MATLAB仿真代码
  16. php网站 视频马赛克,如何给视频加马赛克 菜鸟也能学会的视频加马赛克解决方案...
  17. dell服务器开机进系统黑屏,dell电脑开机黑屏,教你几步解决_故障
  18. Oracle汉字排序nls_sort
  19. 有哪些可以快速回复信息的软件
  20. Qt6-在线获取和安装

热门文章

  1. Java读写文件的几种方式
  2. 一文带你深入理解JVM内存模型
  3. oracle的获取年月日时间,获取5年前日期
  4. open-capacity-platform 项目启动
  5. ROM微型计算机是什么,在微型计算机中,ROM是().
  6. 3-Qt6命令行输出显示
  7. 计算机应用技术商务网站运营,计算机应用技术云计算与商务网站运营有什么区别...
  8. set集合判断集合中是否有无元素_集合 (Set) | 一山不容二虎的 Python 数据类型
  9. 疑似高能粒子射线导致服务程序异常
  10. java重新执行_(转载)java线程 - 线程唤醒后并被执行时,是在上次阻塞的代码行重新往下执行,而不是从头开始执行...