序列化 - Kryo序列化详解

什么是序列化

序列化是指将数据结构或对象转换为可存储或传输的格式,以便在稍后的时间点重新构建或恢复原始数据结构或对象的过程。在计算机科学和编程中,序列化通常用于将内存中的数据转换为可以在磁盘上保存或通过网络传输的形式,以便在需要时进行持久化存储或在不同系统之间进行数据交换。

序列化的主要目的是在不同的环境中传递数据,无论是在不同的程序之间、不同的计算机之间,甚至在不同的编程语言之间。序列化的结果通常是一串字节流或文本,这取决于所使用的序列化格式。

大白话介绍下RPC中序列化的概念,可以简单理解为对象-->字节的过程,同理,反序列化则是相反的过程。为什么需要序列化?因为网络传输只认字节。所以互信的过程依赖于序列。

jdk序列化

实体类需要实现Serializable接口,以告知其可被序列化

class Student implements Serializable{  
   private String name;  
}  

class Main{
   public static void main(String[] args) throws Exception{  
      // create a Student
      Student st = new Student("kirito");  
     // serialize the st to student.db file  
     ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student.db"));  
     oos.writeObject(st);  
     oos.close();  
     // deserialize the object from student.db
     ObjectInputStream ois = new ObjectInputStream(new FileInputStream("student.db"));  
     Student kirito = (Student) ois.readObject();  
     ois.close();  
    // assert
    assert "kirito".equals(kirito.getName());  
   }  
}

kryo序列化

kryo号称Java中最快的序列化框架,kryo是一个高性能的序列化/反序列化工具,由于其变长存储特性并使用了字节码生成机制,拥有较高的运行速度和较小的体积。

特点:

  1. 序列化的性能非常高
  2. 序列化结果体积较小
  3. 提供了简单易用的API
    记录类型信息
    这算是kryo的一个特点,可以把对象信息直接写到序列化数据里,反序列化的时候可以精确地找到原始类信息,不会出错,这意味着在写readxxx方法时,无需传入Class或Type类信息。

相应的,kryo提供两种读写方式。记录类型信息的writeClassAndObject/readClassAndObject方法,以及传统的writeObject/readObject方法。

引入依赖

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

基础使用

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();
       System.out.println(object2.value);
  }
​
   static public class SomeClass {
       String value;
  }
}

1.Kryo的IO

Kryo致力以简单易用的API,序列化过程中主要核心有Kryo、Output、Input。

Output和Input是Kryo的IO,他们支持以byte array或者stream的形式为序列化的dest和反序列化的source。当使用stream形式进行写出写入时,需要close这些Output和Input。

写出时,当OutputDe buffer是满的时候,就会flush bytes到stream中。写入时,会从stream中获取bytes到Input buffer中,当填充满时,进行反序列化。

2.Kryo的注册

和很多其他的序列化框架一样,Kryo为了提供性能和减小序列化结果体积,提供注册的序列化对象类的方式。在注册时,会为该序列化类生成int ID,后续在序列化时使用int ID唯一标识该类型。

注册的方式如下:

kryo.register(SomeClass.class);

或者

kryo.register(SomeClass.class, 1);

可以明确指定注册类的int ID,但是该ID必须大于等于0。如果不提供,内部将会使用int++的方式维护一个有序的int ID生成。

posted @ 2023-08-14 12:58  杨业壮  阅读(548)  评论(0编辑  收藏  举报