ByVie

序列化流与反序列化流

ObjectOutputStream(序列化流)

ObjectOutputStream是序列化流,可以将Java程序中的对象写到文件中。

ObjectOutputStream 构造方法:

ObjectOutputStream(OutputStream out):参数要传递字节输出流。

ObjectOutputStream写对象的方法(特有方法):

void writeObject(Object obj): 向文件中写对象。

ObjectOutputStream 的使用步骤:

  • 创建序列化流,用来写。
  • 调用 writeObject 方法,写对象。
  • 释放资源。

tips: 要使用序列化流向文件中写的对象,必须实现 Serializable 接口。

public class Demo01ObjectOutputStream {
    public static void main(String[] args) throws IOException {
        //1. 创建序列化流,用来写
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day12\\file03-obj.txt"));
        //2. 调用writeObject方法,写对象
        Person p = new Person("张三丰", 100);
        oos.writeObject(p);
        //3. 释放资源。
        oos.close();
    }
}

ObjectInputStream(反序列化流)

ObjectInputStream 是反序列化流, 可以将文件中的对象读取到 Java 程序中。

ObjectInputStream 的构造方法:

ObjectInputStream(InputStream in):参数要传递字节输入流。

ObjectInputStream 读取对象的方法(特有的方法):

Object readObject(): 从文件中读取对象,并将该对象返回。

反序列化流的使用步骤:

  • 创建 ObjectInputStream 反序列化流。
  • 调用 readObject 方法,读取对象。
  • 释放资源。

tips:调用 readObject 方法读取对象时,对象所对应的类不存在,那么会报错(ClassNotFoundException)

特殊情况:

被 static 修饰的成员变量无法序列化,无法写到文件。

如果不希望某个成员变量写到文件,同时又不希望使用 static 关键字, 那么可以使用 transient。transient 关键字表示瞬态,被 transient 修饰的成员变量无法被序列化。

public class Demo03StaticAndTransient {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        writePerson();
        readPerson();
    }

    //从文件中读取Person对象
    public static void readPerson() throws IOException, ClassNotFoundException {
        //创建反序列化流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day12\\file04-obj.txt"));
        //从文件中读取对象
        Object obj = ois.readObject();
        System.out.println(obj);
        //释放资源
        ois.close();
    }

    //向文件中写Person对象
    public static void writePerson() throws IOException {
        //创建序列化流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day12\\file04-obj.txt"));
        //向文件中写Person对象
        oos.writeObject(new Person("张三丰", 100));
        //关流
        oos.close();
    }
}
public class Demo04SerialVersionUID {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //writePerson();
        readPerson();
    }

    //从文件中读取Person对象
    public static void readPerson() throws IOException, ClassNotFoundException {
        //创建反序列化流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day12\\file04-obj.txt"));
        //从文件中读取对象
        Object obj = ois.readObject();
        System.out.println(obj);
        //释放资源
        ois.close();
    }

    //向文件中写Person对象
    public static void writePerson() throws IOException {
        //创建序列化流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day12\\file04-obj.txt"));
        //向文件中写Person对象
        oos.writeObject(new Person("张三丰", 100));
        //关流
        oos.close();
    }
}

例题

/*
    练习:
        1. 将存有多个Student对象的集合序列化操作,保存到list.txt 文件中。
        2. 反序列化list.txt ,并遍历集合,打印对象信息。

    步骤:
        1. 创建集合,用来保存Student
        2. 向集合中添加Student对象。
        3. 创建ObjectOutputStream序列化流,用来写。
        4. 调用writeObject方法,向文件中写集合对象。
        5. 释放资源。
        6. 创建ObjectInputStream反序列化流对象,用来读取
        7. 调用readObject方法,从文件中读取对象。
        8. 将读取到的集合进行遍历,并输出结果。

    注意:如果想要将多个对象保存在文件中,最好的一个方式可以将多个对象放入到一个集合中,然后直接将集合写到文件中。
 */
public class Demo05Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //1. 创建集合,用来保存Student
        List<Student> list = new ArrayList<>();
        //2. 向集合中添加Student对象。
        list.add(new Student("李云龙", 20));
        list.add(new Student("二营长", 22));
        list.add(new Student("秀琴", 25));
        //3. 创建ObjectOutputStream序列化流,用来写。
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day12\\list.txt"));
        //4. 调用writeObject方法,向文件中写集合对象。
        oos.writeObject(list);
        //5. 释放资源。
        oos.close();
        //6. 创建ObjectInputStream反序列化流对象,用来读取
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day12\\list.txt"));
        //7. 调用readObject方法,从文件中读取对象。
        List<Student> list2 = (List<Student>) ois.readObject();
        //8. 将读取到的集合进行遍历,并输出结果。
        for (Student stu : list2) {
            System.out.println(stu);
        }
    }
}