File类与常用IO流第十章——序列化流

时间:2023-03-08 21:42:38
  • 第十章、序列化流

  • 序列化流和反序列化流概述

    • 序列化:用一个字节序列表示一个对象,该字节序列包含该对象的数据、对象的类型和对象中存储的属性等等信息。字节序列写出到文件后,相当于文件中持久保存了一个对象的信息。

    • 反序列话:从文件中将字节序列读取回来,重构对象。

    • 序列化与反序列化图示1:

    • File类与常用IO流第十章——序列化流

    • 序列化与反序列化图示2:

    • File类与常用IO流第十章——序列化流

  • Serializable

    • 序列化和反序列化的时候,会抛出NotSerializableException,没有序列化异常。

    • 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。

    • Serializable接口也叫标记型接口。类实现了Serializable接口就会给类添加一个标记,要进行序列化和反序列化的时候,就会检测类上是否有这个标记。有则可以进行序列化或反序列化;没有则会抛出 NotSerializableException 异常。

  • static

    • 静态优先于非静态加载到内存中(静态优先于对象进入内存中)

    • 被static修饰的成员变量不能被序列化,序列化的都是对象。如 private static int age; oos.writeObject(new Person("小美女",18));

      • 序列化得到的是:Person{name='小美女', age=0}

  • transient

    • 瞬态关键字。

    • 被transient修饰的成员变量,不能被序列化。 private transient int age; oos.writeObject(new Person("小美女",18));

      • 序列化得到是:Person{name='小美女', age=0}

  • 对象的序列化

    • 概述:java.io.ObjectOutputStream extends OutputStream

    • 构造方法

      • ObjectOutputStream(OutputStream out ):创建写入指定os的oos

      • os,字节输出流。

    • 特有的成员方法:

      • void writeObject(Object obj):将指定的对象写入oos中。

    • 使用步骤:

  1. 创建oos对象,构造方法中传递字节输出流;

  2. 使用oos对象中的方法writeObject,把对象写入到文件中;

  3. 释放资源。

  • 代码示意:

  • 1 public class Person implements Serializable{
    2 private static final long serialVersionUID = 1L;
    3 private String name;
    4 private int age;
    5 get...set..
    6 toString...
    7 }
    1 //1.创建ObjectOutputStream对象,构造方法中传递字节输出流
    2 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("10_IO\\person.txt"));
    3 //2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
    4 oos.writeObject(new Person("小美女",18));
    5 //3.释放资源
    6 oos.close();
    • 对象的反序列化:

      • 概述:java.io.ObjectInputStream extends InputStream

      • 构造方法:

        • ObjectInputStream(InputStream in):创建从指定in读取的ois对象。

      • 特有的成员方法:

        • Object readObject() :从ois中读取对象。

      • 使用步骤:

    1. 创建ois对象,构造方法中传递字节输入流;

    2. 使用ois对象中的方法readObject读取保存对象的文件;

    3. 释放资源;

    4. 处理读取到的对象。

  • 注意:readObject方法声明抛出了 ClassNotFoundException(class文件找不到异常)。

  • 反序列化的前提:

    • 类必须实现Serializable。

    • 必须存在类对应的class文件。

  • 代码示意:

  •  1 public static void main(String[] args) throws IOException, ClassNotFoundException {
    2 //1.创建ObjectInputStream对象,构造方法中传递字节输入流
    3 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("10_IO\\person.txt"));
    4 //2.使用ObjectInputStream对象中的方法readObject读取保存对象的文件
    5 Object o = ois.readObject();
    6 //3.释放资源
    7 ois.close();
    8 //4.使用读取出来的对象(打印)
    9 System.out.println(o);
    10 Person p = (Person)o;
    11 System.out.println(p.getName()+p.getAge());
    12 }
     
    • InvalidClassExcepton异常原理,如下示意图:

    File类与常用IO流第十章——序列化流

    • 序列化集合

      • 题目描述:序列化集合。当想要在文件中保存多个对象的时候,可以把多个对象存储到一个集合中。对集合进行序列化和反序列化操作。

      • 步骤分析:

    1. 定义一个存储Person对象的ArrayList集合;

    2. 往ArrayList集合中存储Person对象;

    3. 创建一个序列化流oos对象

    4. 使用oos对象中方法writeObject,对集合进行序列化;

    5. 创建一个反序列化ois对象;

    6. 使用ois对象中的方法readObject读取文件中保存的集合;

    7. 把Object类型的集合转换为ArrayList类型;

    8. 遍历ArrayList集合;

    9. 释放资源。

  • 代码实现:

  •  1 public static void main(String[] args) throws IOException, ClassNotFoundException {
    2 //1.定义一个存储Person对象的ArrayList集合
    3 ArrayList<Person> list = new ArrayList<>();
    4 //2.往ArrayList集合中存储Person对象
    5 list.add(new Person("张三",18));
    6 list.add(new Person("李四",19));
    7 list.add(new Person("王五",20));
    8 //3.创建一个序列化流ObjectOutputStream对象
    9 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("10_IO\\list.txt"));
    10 //4.使用ObjectOutputStream对象中的方法writeObject,对集合进行序列化
    11 oos.writeObject(list);
    12 //5.创建一个反序列化ObjectInputStream对象
    13 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("10_IO\\list.txt"));
    14 //6.使用ObjectInputStream对象中的方法readObject读取文件中保存的集合
    15 Object o = ois.readObject();
    16 //7.把Object类型的集合转换为ArrayList类型
    17 ArrayList<Person> list2 = (ArrayList<Person>)o;
    18 //8.遍历ArrayList集合
    19 for (Person p : list2) {
    20 System.out.println(p);
    21 }
    22 //9.释放资源
    23 ois.close();
    24 oos.close();
    25 }