Java IO 读写对象流 序列化&反序列化
序列化 对象中的数据(非static修饰的成员变量) 以字节流 写入 被文件中存储 “写对象”
反序列化 文件中存储的“类对象”的数据 以字节流 读出 依靠对应类编译后的class文件的存在 再次被解读还原 “读对象”
写对象的类 ObjectOutputStream
其构造方法: ObjectOutputStream(OutputSteam out)
写对象的方法: writeObject(Object obj )
读对象的类 ObjectInputStream
其构造方法:ObjectInputStream(InputStream in)
读对象的方法: Object obj =ois.readObject() // 读取获得的是万能的Object类型的对象 实际使用对象 需要强制向下转具体类型
向流中写入对象的操作 称为 序列化
从流中读取对象的操作 成为 反序列化
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public static void writeObject() throws IOException{ //创建字节输出流,封装文件 FileOutputStream fos = new FileOutputStream("c:\\person.txt"); //创建写出对象的序列化流的对象,构造方法传递字节输出流 ObjectOutputStream oos = new ObjectOutputStream(fos); Person p = new Person("lisi",25); //调用序列化流的方法writeObject,写出对象 oos.writeObject(p); oos.close(); }
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public static void readObject() throws IOException, ClassNotFoundException{ FileInputStream fis = new FileInputStream("c:\\person.txt"); //创建反序列化流,构造方法中,传递字节输入流 ObjectInputStream ois = new ObjectInputStream(fis); //调用反序列化流的方法 readObject()读取对象 Object obj =ois.readObject(); System.out.println(obj); ois.close(); }
注意 可以被序列化操作的对象 必须是被“标记”了 Serialiazable 的对象
被序列化的类 需要先implements Serializable 实现“序列化”接口 (该接口被认为是一种 标记型接口 因为这种接口内 没有定义任何方法! 此类接口 只起到“打标记”的作用) 类似的标记接口 还有 java.lang包下的 克隆接口
类中某些属性 不想被序列化写入 可以用关键字 transient 修饰 不序列化即不可持久存储 因此 此关键字被称为 瞬态关键字
类中的 被static修饰的属性 也不会被序列化 因为 序列化 针对的是类的对象 而不是类 static修饰的属性 属于类 不属于对象
为防止反序列化的失败 可以在类的源码文件中 添加自定义序列号 private static final long serialVersionUID = 1478652478456L;
添写了序列号的源码文件中 即便修改源文件中类的属性 编译器对源文件重新编译后生成新的 .class文件 该class文件的序列号 依然也会固定保持不变
只有序列号一致 没有任何冲突! 读对象 反序列化 才能顺利成功!