Java缓冲流、转换流、序列化流( 五 )


反序列化操作1
如果能找到一个对象的class文件,我们可以进行反序列化操作,调用 ObjectInputStream 读取对象的方法:
public final Object readObject () : 读取一个对象 。
public class DeserializeDemo {public static void main(String [] args) {Employee e = null; try {// 创建反序列化流FileInputStream fileIn = new FileInputStream("employee.txt"); ObjectInputStream in = new ObjectInputStream(fileIn);// 读取一个对象e = (Employee) in.readObject();// 释放资源in.close(); fileIn.close();}catch(IOException i) {// 捕获其他异常i.printStackTrace(); return;}catch(ClassNotFoundException c) {// 捕获类找不到异常System.out.println("Employee class not found"); c.printStackTrace();return;}// 无异常,直接打印输出System.out.println("Name: " + e.name); // zhangsan System.out.println("Address: " + e.address); // beiqinglu System.out.println("age: " + e.age); // 0}}对于JVM可以反序列化对象,它必须是能够找到class文件的类 。如果找不到该类的class文件,则抛出一个 ClassNotFoundException 异常 。
反序列化操作2
另外,当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操 作也会失败,抛出一个 InvalidClassException 异常 。发生这个异常的原因如下:
该类的序列版本号与从流中读取的类描述符的版本号不匹配
该类包含未知数据类型
该类没有可访问的无参数构造方法
Serializable 接口给需要序列化的类,提供了一个序列版本号 。serialVersionUID 该版本号的目的在于验证序 列化的对象和对应类是否版本匹配 。
public class Employee implements java.io.Serializable {// 加入序列版本号private static final long serialVersionUID = 1L; public String name;public String address;// 添加新的属性 ,重新编译, 可以反序列化,该属性赋为默认值. public int eid;public void addressCheck() {System.out.println("Address check : " + name + " ‐‐ " + address);}}3.4练习:序列化集合

  1. 将存有多个自定义对象的集合序列化操作,保存到 list.txt 文件中 。
  2. 反序列化 list.txt,并遍历集合,打印对象信息 。
  3. 案例分析
  4. 1.把若干学生对象,保存到集合中 。
  5. 2.把集合序列化 。
  6. 3.反序列化读取时,只需要读取一次,转换为集合类型 。
  7. 4.遍历集合,可以打印所有的学生信息
  8. 案例实现
【Java缓冲流、转换流、序列化流】public class SerTest {public static void main(String[] args) throws Exception {// 创建 学生对象Student student = new Student("老王", "laow"); Student student2 = new Student("老张", "laoz"); Student student3 = new Student("老李", "laol");ArrayList<Student> arrayList = new ArrayList<>(); arrayList.add(student);arrayList.add(student2); arrayList.add(student3);// 序列化操作// serializ(arrayList);// 反序列化ObjectInputStream ois = new ObjectInputStream(new FileInputStream("list.txt"));// 读取对象,强转为ArrayList类型ArrayList<Student> list = (ArrayList<Student>)ois.readObject();for (int i = 0; i < list.size(); i++ ){ Student s = list.get(i);System.out.println(s.getName()+"‐‐"+ s.getPwd());}}private static void serializ(ArrayList<Student> arrayList) throws Exception {// 创建 序列化流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.txt"));// 写出对象oos.writeObject(arrayList);// 释放资源oos.close();}}第四章 打印流4.1概述
平时我们在控制台打印输出,是调用 print 方法和 println 方法完成的,这两个方法都来自于 java.io.PrintStream 类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式 。
4.2PrintStream类
构造方法
public PrintStream(String fileName) : 使用指定的文件名创建一个新的打印流 。
构造举例,代码如下:
PrintStream ps = new PrintStream("ps.txt");改变打印流向
System.out 就是 PrintStream 类型的,只不过它的流向是系统规定的,打印在控制台上 。不过,既然是流对象,我们就可以玩一个"小把戏",改变它的流向 。
public class PrintDemo {public static void main(String[] args) throws IOException {// 调用系统的打印流,控制台直接输出97 System.out.println(97);// 创建打印流,指定文件的名称PrintStream ps = new PrintStream("ps.txt");// 设置系统的打印流流向,输出到ps.txt System.setOut(ps);// 调用系统的打印流,ps.txt中输出97System.out.println(97);}}



推荐阅读