I/O流——序列化与反序列化

Serialization(序列化):将java对象以一连串的字节保存在磁盘文件中的过程,也可以说是保存java对象状态的过程。序列化可以将数据永久保存在磁盘上(通常保存在文件中)。

deserialization(反序列化):将保存在磁盘文件中的java字节码重新转换成java对象称为反序列化。

        序列化就好比将一只动物的基因分解,封装在一个容器中;反序列化就是将容器中封装的基因序列拿出来重新组装成一只动物,组装前和组装后的动物是不同的,但是基因是一样的。

下面来实现一个序列化:

1.首先创建一个Student对象

public class Student implements Serializable {
    private String name;// 姓名
    private String gender;// 性别
    private Integer age;// 年龄

    public Student() {// 无参构造
    }

    public Student(String name, String gender, Integer age) {// 有参构造
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    @Override
    public String toString() {// toString()方法
        return "Student{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {// get方法
        return name;
    }

    public void setName(String name) {// set方法
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

注意!这里的Student类要实现一个Serializable接口,否则会报NotSerializableException(没有序列化异常)

2.给Student对象赋值,在控制台可以打印一下

Student student = new Student("小明", "男", 15);
System.out.println(student.getName());
System.out.println(student.getGender());
System.out.println(student.getAge());

序列化用到两个类:

(1)FileOutputStream:文件字节输出流。

        是用于将数据写入 File 或 FileDescriptor 的输出流。文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。

(2)ObjectOutputStream:对象输出流。

        将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。
 

public static void main(String[] args) {

        // 序列化 将student类的对象序列化到abc.txt文件中

        Student student = new Student("小明", "男", 15);
        System.out.println(student.getName());
        System.out.println(student.getGender());
        System.out.println(student.getAge());

        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream("./resources/bb.txt");
            oos = new ObjectOutputStream(fos);
            oos.writeObject(student);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
        }
    }
}

控制台输出:

I/O流——序列化与反序列化_第1张图片

序列化后再路径下面会生成对应的文件:

I/O流——序列化与反序列化_第2张图片

但是生成的文件打开后是乱码:

这个乱码文件不是我们代码写错了,而是用计算机语言存储的一个二进制文件,后续进行反序列化就可以直接将这个二进制文件变为Student对象。


 实现反序列化也用到两个类:

(1)FileInputStream:文件字节输入流。

        是Java语言中抽象类InputStream用来具体实现类的创建对象。FileInputStream可以从文件系统中的某个文件中获得输入字节,获取的文件可用性取决于主机环境。FileInputStream的构造方法需要指定文件的来源,通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的 File 对象 file 指定。

(2)ObjectInputStream:对象输出流。

        从流中读入一个用户自定义的对象。一定要注意ObjectOutputStream与ObjectInputStream必须配合使用,且按同样的顺序。

public static void main(String[] args) {
// 反序列化
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        try {
            fis = new FileInputStream("./resources/bb.txt");
            ois = new ObjectInputStream(fis);
            Student student = (Student)ois.readObject();
            System.out.println(student.getName());
            System.out.println(student.getAge());
            System.out.println(student.getGender());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

反序列化时还要注意要将读取的对象强转为Student类:

I/O流——序列化与反序列化_第3张图片

你可能感兴趣的:(javase学习,java,开发语言)