Java 序列化工具

Java 序列化工具

简介

序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。Java 本身提供了 Serializable 类,通过继承此类可以方便的将数据进行序列化。

除此之外可以使用如下提到的第三方框架。

Kryo

Kryo 是一个快速高效的 Java 二进制对象图序列化框架。该项目的目标是高速、小尺寸和易于使用的 API。该项目在需要持久化对象的任何时候都很有用,无论是构建文件、存储至数据库还是通过网络传输对象。

Kryo 还可以执行自动深浅复制/克隆。这是从对象到对象的直接复制,而不是从对象到字节到对象的直接复制。

简单使用

首先需要引入依赖包:

1
2
3
4
5
6

<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>5.3.0</version>
</dependency>

然后可以参照此样例完成代码编写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

import java.io.*;

public class HelloKryo {
static public void main(String[] args) throws Exception {
Kryo kryo = new Kryo();
kryo.register(SomeClass.class);

SomeClass object = new SomeClass();
object.value = "Hello Kryo!";

Output output = new Output(new FileOutputStream("file.bin"));
kryo.writeObject(output, object);
output.close();

Input input = new Input(new FileInputStream("file.bin"));
SomeClass object2 = kryo.readObject(input, SomeClass.class);
input.close();
}

static public class SomeClass {
String value;
}
}

Avro

Apache Avro 是一个数据序列化系统。

Avro 提供:

  • 丰富的数据结构。
  • 一种紧凑、快速的二进制数据格式。
  • 一个容器文件,用于存储持久数据。
  • 远程过程调用 (RPC)。
  • 与动态语言的简单集成。代码生成不需要读取或写入数据文件,也不需要使用或实现 RPC 协议。代码生成作为一种可选的优化,只为静态类型语言实现。

简单使用

首先需要引入依赖包:

1
2
3
4
5
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.11.0</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<plugins>
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.11.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>

Avro 在序列化时是需要提前定义结构:

1
2
3
4
5
6
7
8
9
{"namespace": "example.avro",
"type": "record",
"name": "User",
"fields": [
{"name": "name", "type": "string"},
{"name": "favorite_number", "type": ["int", "null"]},
{"name": "favorite_color", "type": ["string", "null"]}
]
}

然后根据所指定的结构编译 Java 文件,将目标文件放在代码中:

1
java -jar /path/to/avro-tools-1.11.0.jar compile schema <schema file> <destination>

编写样例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class Test {
public static void main(String[] args) {
User user1 = new User();
user1.setName("Alyssa");
user1.setFavoriteNumber(256);

User user2 = new User("Ben", 7, "red");

User user3 = User.newBuilder()
.setName("Charlie")
.setFavoriteColor("blue")
.setFavoriteNumber(null)
.build();

DatumWriter<User> userDatumWriter = new SpecificDatumWriter<User>(User.class);
DataFileWriter<User> dataFileWriter = new DataFileWriter<User>(userDatumWriter);
dataFileWriter.create(user1.getSchema(), new File("users.avro"));
dataFileWriter.append(user1);
dataFileWriter.append(user2);
dataFileWriter.append(user3);
dataFileWriter.close();

DatumReader<User> userDatumReader = new SpecificDatumReader<User>(User.class);
DataFileReader<User> dataFileReader = new DataFileReader<User>(file, userDatumReader);
User user = null;
while (dataFileReader.hasNext()) {
user = dataFileReader.next(user);
System.out.println(user);
}
}
}

参考资料

Kryo

Avro


Java 序列化工具
https://wangqian0306.github.io/2022/serialization/
作者
WangQian
发布于
2022年6月27日
许可协议