(反)序列化流

简介: (反)序列化流

序列化是将对象转换为字节序列的过程,以便在网络上传输或持久化到存储介质中。而序列化流(ObjectInputStream 和 ObjectOutputStream)是 Java 中用于进行对象序列化和反序列化的工具类。

在 Java 中,主要使用 java.io.ObjectInputStreamjava.io.ObjectOutputStream 类来实现序列化流的功能。

  1. ObjectOutputStream 用于将对象序列化为字节流。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
try (FileOutputStream fileOut = new FileOutputStream("object.ser");
     ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
    MyClass obj = new MyClass();
    out.writeObject(obj);
    // 对象已成功序列化为字节流
} catch (IOException e) {
    e.printStackTrace();
}
  1. 在上述示例中,创建了一个 ObjectOutputStream 对象,并传入一个底层的 FileOutputStream 作为字节输出流。然后,通过 writeObject 方法将一个对象(MyClass 类的实例)写入到输出流中,从而将其序列化为字节流。
  2. ObjectInputStream 用于将字节流反序列化为对象。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
try (FileInputStream fileIn = new FileInputStream("object.ser");
     ObjectInputStream in = new ObjectInputStream(fileIn)) {
    MyClass obj = (MyClass) in.readObject();
    // 字节流已成功反序列化为对象
} catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
}
  1. 在上述示例中,创建了一个 ObjectInputStream 对象,并传入一个底层的 FileInputStream 作为字节输入流。然后,通过 readObject 方法从输入流中读取字节,并将其反序列化为对象(此处假设被读取的字节流确实表示一个 MyClass 对象)。

当涉及到序列化流的细节时,有一些重要的方面需要注意:

  1. 实现 Serializable 接口:要使一个对象可以被序列化,它的类必须实现 java.io.Serializable 接口。这是一个标记接口,没有定义任何方法。通过实现该接口,编译器将知道该类可以被序列化,并且可以将其对象转换为字节流。
  2. 序列化和反序列化的字段匹配:在进行序列化和反序列化时,对象的字段(即实例变量)将被写入和读取。确保被序列化和反序列化的对象具有相同的字段和字段顺序非常重要。如果序列化和反序列化的对象之间的字段不匹配,可能会导致数据损坏或异常。
  3. 版本控制:当序列化的类发生更改时,例如添加、删除或修改字段,建议为该类提供一个固定的版本号(serialVersionUID)。这样做可以在反序列化过程中提供版本控制,避免出现意外的问题。要自定义版本号,可以在类中添加以下代码:
private static final long serialVersionUID = 123456789L;
  1. 序列化多个对象:可以将多个对象连续地写入序列化流,然后再按照相同的顺序连续地从反序列化流中读取。这样可以将整个对象图保存到一个文件中,或者在网络上一次性传输多个对象。
  2. 序列化的限制:某些对象可能无法序列化。例如,如果对象中包含不可序列化的字段(如线程、文件句柄等),则会导致序列化失败。在这种情况下,可以通过将字段标记为 transient 来排除它们,使其不参与序列化过程。
  3. 序列化流的关闭:使用序列化流时,应该始终使用 try-with-resources 或手动关闭资源。序列化流中的缓冲区在关闭时会自动刷新并将剩余的数据写入到输出流中。

 

实例:

假设有一个学生类,用序列流写出一个学生

import java.io.Serializable;
public class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;
    private String studentId;
    public Student(String name, int age, String studentId) {
        this.name = name;
        this.age = age;
        this.studentId = studentId;
    }
    // 省略了getter和setter方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", studentId='" + studentId + '\'' +
                '}';
    }
}

接下来,我们将使用序列化流将一个学生对象写出到文件中。

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Main {
    public static void main(String[] args) {
        Student student = new Student("张三", 20, "20210001");
        try (FileOutputStream fileOut = new FileOutputStream("student.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
            out.writeObject(student);
            System.out.println("学生对象已成功写出到文件");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

以下是使用序列化流将学生对象写入idea的代码:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Main {
    public static void main(String[] args) {
        try (FileInputStream fileIn = new FileInputStream("student.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn)) {
            Student student = (Student) in.readObject();
            System.out.println(student);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}


相关文章
|
4月前
|
存储 Java
JaveSE—IO流详解:对象输入输出流(序列化及反序列化)
JaveSE—IO流详解:对象输入输出流(序列化及反序列化)
|
安全 Java
字节数组流和数据流
字节数组流和数据流
74 0
|
6月前
|
存储 Java
对象序列化流和对象反序列化流
对象序列化流和对象反序列化流
70 0
|
存储 Java
|
Java 对象存储
对象流的序列化和反序列化
对象流的序列化和反序列化
46 0
|
存储 XML JSON
网络传输 | 序列化与反序列化
网络传输 | 序列化与反序列化
567 0
网络传输 | 序列化与反序列化
Java开发——31.I/O流_处理流(对象流),对象的序列化机制
对象的序列化机制:允许把内存中的Java对象转换成和平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点(序列化);其它程序获取了这种二进制流,就可以恢复成原来的Java对象(反序列化)。
Java开发——31.I/O流_处理流(对象流),对象的序列化机制
30 IO流再回顾,深入理解序列化和反序列化
IO流再回顾,深入理解序列化和反序列化
82 0
|
存储 算法 Java
IO流的序列化和反序列化
序列化:指把堆内存中的 Java 对象数据,通过某种方式把对象存储到磁盘文件中或者传递给其他网络节点(在网络上传输)。这个过程称为序列化。通俗来说就是将数据结构或对象转换成二进制串的过程
172 0