序列化流(对象操作输出流):
可以把java中的对象写到本地文件中。
public objectoutputstream(outputstream out) 把基本流包装成高级流。
public final void writeobject(object obj) 把对象序列化(写出)到文件中去。
细节:使用序列化流将对象保存到文件时会出现NotSerializableException异常,可以采取让javabean类实现Serializable接口来解决问题。
Serializable接口里面时没有抽象方法的,是一个标记型接口,一旦实现了这个接口,那么就表示当前类可以被序列化。
案例需求:利用序列化流,把一个对象写到本地文件中。
代码实现:
package com.zhou.myobjectstream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ObjectStreamDemo01 {
public static void main(String[] args) throws IOException {
/*需求:利用序列化流,把一个对象写到本地文件中*/
//1.创建对象
Student stu = new Student("张三",23);
//2.创建序列化流的对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\IdeaFile\\MyIO\\AnLi.txt"));
//3.写出数据
oos.writeObject(stu);
//4.释放资源
oos.close();
}
}
再写一个Student类:
package com.zhou.myobjectstream;
import java.io.Serializable;
public class Student implements Serializable {
public Student(){
}
public Student(String name,int age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "Student{name = " + name + ", age = " + age + "}";
}
private String name;
private int age;
}
运行结果:
此时,Student类便被序列化后被保存到了文件当中。
反序列化流:
可以把序列化到本地文件中的对象,去读到程序中来。
public objectInputstream( Inputstream out) 把基本流变成高级流
public object readobject() 把序列化到本地文件中的对象,读取到程序中来
案例需求:利用序列化流,把一个本地文件职中的对象读到程序中。
代码实现:
package com.zhou.myobjectstream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ObjectStreamDemo02 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
/*利用序列化流,把一个本地文件职中的对象读到程序中。*/
//1.创建反序列化流的对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\IdeaFile\\MyIO\\AnLi.txt"));
//2.读取数据
Object o = ois.readObject();
//3.打印对象
System.out.println(o);
//4.关闭资源
ois.close();
}
}
注意:读取到的数据是Object类型的!如果想要真正的Stdent类,还需要做一个强转。
Student o = (Student) ois.readObject();
其运行结果是一致的。
序列化流及反序列化流使用细节:
在建好对象后,使其实现Serializable接口,再对其实现序列化将其保存到本地文件当中,当我们修改对象时,再使用反序列化将其从本地文件以对象的形式读到程序当中,会出下报错,这是因为每一次序列化,都会根据对象中所包含的所有成员生成一个版本号,序列化后,文件当中也会包含这个版本号此时,如果修改了java文件,会导致文件中的版本号和JavaBean的版本号不匹配,从而报错。
因为在实际开发中,必须根据业务对Javabean进行修改,所以不更改JavaBean是不可能的,所以解决方案应该是,固定一个版本号。
版本号命名格式:private static final long serialVersionUID = 1L;
如果有在JavaBean文件中,有不想被序列化的成员变量,可以在成员变量前面加上transient(瞬态)关键字。
transient的作用:不会把当前属性序列化到本地文件当中。
练习:
将多个自定义对象序列化到文件中,但是对象的个数不确定,该如何操作呢?
可以将对象全部放到ArrayList集合当中,对ArrayList序列化,在读的时候只需要对集合实现遍历即可。
接下来实现:
先写好一个对象:
package com.zhou.myobjectstream;
import java.io.Serializable;
public class Teacher implements Serializable {
private static final long serialVersionUID = -1108545422521561957L;
public Teacher(){
}
public Teacher(String name,String sex,int age){
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Teacher{" + "name='" + name + '\'' + ", sex='" + sex + '\'' + ", age=" + age + '}';
}
private String name;
private String sex;
private int age;
}
序列化流:
package com.zhou.myobjectstream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
public class ObjectStreamDemo03 {
public static void main(String[] args) throws IOException {
Teacher t1 = new Teacher("章程","男",41);
Teacher t2 = new Teacher("李元","男",36);
Teacher t3 = new Teacher("周强","男",57);
ArrayList<Teacher> list = new ArrayList<>();
list.add(t1);
list.add(t2);
list.add(t3);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\IdeaFile\\MyIO\\XuLie.txt"));
oos.writeObject(list);
oos.close();
}
}
反序列化流,读取对象:
package com.zhou.myobjectstream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
public class ObjectStreamDemo04 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\IdeaFile\\MyIO\\XuLie.txt"));
ArrayList<Teacher> list = (ArrayList<Teacher>)ois.readObject();
for(Teacher teacher : list){
System.out.println(teacher);
}
ois.close();
}
}
另外准备好一个本地文件用于保存JavaBean文件:
运行结果: