专业的编程技术博客社区

网站首页 > 博客文章 正文

JAVA序列化工具之protobuf、messagepack

baijin 2025-01-13 10:47:55 博客文章 7 ℃ 0 评论

知识要点

  1. JAVA默认序列化
  2. MessagePack序列化工具
  3. protobuf序列化工具

本文对以上三种序列化后流大小比较以及工具简单的使用


  • JAVA默认序列化
//实现Serializable接口
User user = new User();
user.setId(1);
user.setName("张三");

ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(out);
outputStream.writeObject(user);
outputStream.flush();
outputStream.close();

byte[] byteArrays = out.toByteArray();
System.out.println("java序列化的流大小:"+byteArrays.length);
//输出结果:java序列化的流大小:187


  • MessagePack序列化工具

对于Maven用户,在pom.xml文件中添加以下命令:

	<dependency>
			<groupId>org.msgpack</groupId>
			<artifactId>msgpack</artifactId>
			<version>0.6.12</version>
		</dependency>


MessagePack代码示例:

//注:使用MessagePack序列化时,该对象必须在类上加@Message注解
User user = new User();
user.setId(1);
user.setName("张三");

MessagePack msgpk = new MessagePack();
byte[]  msgBtyes = msgpk.write(user);
System.out.println("MessagePack序列化后流的大小:"+msgBtyes.length);
//输出结果:MessagePack序列化后流的大小:9


//反序列化对象
User userNew =msgpk.read(msgBtyes,User.class);
  • protobuf序列化工具(推荐使用)

添加依赖:protobuf

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

说明:因protobuf是用C ++编写的。对于非C ++用户,需要从github上下载预构建的二进制文件:https://github.com/protocolbuffers/protobuf/releases ,

找到对应自己系统版本,找到C++最新版本的:protoc-3.9.0-rc-1-win64.zip,下载好后解压,后续会通过cmd命令生产java文件。

注:maven中protobuf的version要与你下载的生成器版本保持一致,不然会出现很多问题。


1、手动新建User.proto文件

syntax = "proto2";//固定

package protobuf; //当前文件路径

option java_package = "com.protobuf";//生成Java类后存放路径,生成java文件时会自动创建
option java_outer_classname = "UserProto";//类名,UserProto.java

//内部类,用来保存实例对象
message UserProtoBuf {
  required int64 id = 1; //   类型Long   指定唯一序号, 这个主要用于列对应的值
  required string name = 2; 
}


2、cmd命令进入到我们下载的工具bin路径下,我的放在D盘,执行以下命令:

protoc -I=D:\tools\src\protobuf --java_out=D:\tools\src\main\java\com\protobuf User.proto

说明: -I=D:\tools\src\protobuf 表示你User.proto的物理路径

--java_out=D:\tools\src\main\java 表示生成java类保存的路径

User.proto 表示你对哪一个proto文件生成java类


3、 检查指定路径下是否生成的UserProto.java

UserProto.java类中会有部分方法java.lang.Override报错,这是因为JDK版本原因,删掉即可。

如果出现部分方法错误,请检查自己的maven版本号和生成器的版本号是否一致。

  • protobuf代码示例
//经典的链式调用
//对内部类赋值
UserProto.UserProtoBuf userProBuf = UserProto.UserProtoBuf.newBuilder().setId(1L).setName("张三").build();
byte[] bytes = user.toByteArray();
System.out.println("protobuf流长度:" + bytes.length);
//输出结果protobuf流长度:10
//至于为什么长度比messagePack还多1个,大家可以多加些字段试试


//反序列化调用
UserProto.UserProtoBuf user = UserProto.UserProtoBuf.parseFrom(byte[] data);

扩展要点:

1、如果有多个JAVA对象需要序列化,是否每个类都需要生成?

答:是的,有100个需要生成100个。

2、protobuf目前用到的场景

答:Netty的高性能就默认提供了对GoogleProtobuf的支持。

3、是否支持跨语言

答:在Google官方发布的源代码中包含了c++、java、Python三种语言。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表