反序列化和序列化
- 反序列化:反序列化就是将一个文件当中的字节碎片信息读出来,反向构建成一个完成对象的过程称为反序列化
- 序列化:序列化就是把一个对象拆解成字节碎片的过程叫做序列化
举例
有如下一个student类,里面有个私有的属性,加上一个带参数的构造方法,为了方便取值这里提供一个toString方法。
public class Student {
private String name;
public Student(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
接着我们创建一个这样的对象,正常输出stu的话就能看到重写toString之后的输出,
public class Test {
public static void main(String[] args) {
Student stu = new Student("zhang3");
System.out.println(stu);
}
}
当我们有了这个student之后,我们一new这个student就会在堆内存产生一个空间,而这个new的过程,就是对象在堆内存产生空间的过程。而不管是栈还是堆,都是我们所谓的内存。内存它是一个临时的存储地方,当我们运行程序完毕,关掉之后,它就不存在了。而这时就会涉及一个非常重要的概念叫做数据的持久化。
所谓的持久化就是将一个临时性的数据,把它永久性的保存起来,而所谓的永久保存就是将内存的东西放在文件里,而文件又存在于我们的硬盘上。比如我们经常使用的数据库系统,其实他的本质上都是在硬盘上去操作文件读写管理的过程。
对象的序列化作用
对象序的序列化就是将一个临时性存在内存当中的对象,拆成自己的碎片永久性的写到文件里进行保存。所以当我们明白了什么叫做对象序列化,以及为什么需要做这件事情,那么怎么做就很容易了。
对象序列化
1.需要一个fileOutputStream 文件输出流,然后给一个指定的路径,比如我们把写在D盘的test文件夹下
2.我们还需要一个叫做ObjectOutputStream,它是将对象拆开的一个流。然后我们new一个ObjectOutputStream,而这个流是一个高级流,所以我们可以把fos放进去,刚好就构建出来,他会将对象拆成碎片,然后同时利用底层这个输出流,把它写入文件中。
3.接下来我们只需要用oos去调用他的writeObject()方法将stu所指向的对象写到文件里,最后调用oss.flush清空流管道。
4.而当我们写完这些之后,运行时会发现这时会抛出一个运行时异常,叫做NotSerializableException,而当出现这个异常的时候,就是提醒我们需要让Student去实现一个规则,叫Serializable。这时如果我们点进Serializable看时,你会发现这个接口里面没有任何的方法,所以这种接口他是一个示意型接口。
import java.io.Serializable;
public class Student implements Serializable {
private String name;
public Student(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
public class Test {
public static void main(String[] args) throws Exception {
Student stu = new Student("zhang3");
System.out.println(stu);
// 对象序列化
FileOutputStream fos = new FileOutputStream("D://test/student.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(stu);
oos.flush();
}
}
反序列化
1.需要一个FileInputStream 文件输入流,然后给一个想要读取的文件路径,比如我们把之前D盘的test文件夹下的student.txt的文档读取。
2.我们还需要一个叫做ObjectInputStream,然后我们new一个ObjectInputStream,而这个流也是一个高级流,所以需要一个文件的低级流给他传递。
3.有了ois对象以后我们只需调用他的readObject方法读取对象,当我们读出来之后,还需要组合成一个完整的对象,这时我们需要用Student类型来接收,由于这个方法的返回值是一个object类型,所以我们需要用Student进行强制转换,最后输出即可。
public class Test {
public static void main(String[] args) throws Exception {
// 文件输入流
FileInputStream ifs = new FileInputStream("D://test/student.txt");
ObjectInputStream ois = new ObjectInputStream(ifs);
Student student = (Student) ois.readObject();
System.out.println(student);
}
}