本帖最后由 谢冬 于 2013-3-11 04:19 编辑
控制台的提示信息:
Person [name=张三, age=20, sex=男]
Person [name=王二, age=20, sex=男]
Person [name=李四, age=24, sex=女]
Exception in thread "main" java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2571)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1315)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at com.itheima_01.ObjectOutputStreamDemo.main(ObjectOutputStreamDemo.java:22)
查了文档:当输入过程中意外到达文件或流的末尾时,抛出此异常。
控制台的提示信息:
Person [name=张三, age=20, sex=男]
Person [name=王二, age=20, sex=男]
Person [name=李四, age=24, sex=女]
Exception in thread "main" java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2571)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1315)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at com.itheima_01.ObjectOutputStreamDemo.main(ObjectOutputStreamDemo.java:22)
查了文档:当输入过程中意外到达文件或流的末尾时,抛出此异常。
怎么就意外到达文件末尾,这程序好像没什么意外?能处理吗?怎么处理?
本帖最后由 冯海霞 于 2013-3-11 15:16 编辑 {:soso_e100:}//嘿,让我来解决你的这个问题吧。 //首先,我们在程序开发中,反序列化时,不是使用你的这种方式, //你所使用的这种方式是错误的,是没有根据的,因为我们在查阅API中 //ObjectInputStream的readObject使用说明时,API中并没有说:当对象读到末尾时,返回null。 //正规的方式有两个,当对象不多时,一个一个的读,当对象多时, //我们可以序列化和反序列化一组对象,这样比较方便。一个一个的读,就是序列化了几个, //反序列化时,控制for循环的条件再读回来几个。而序列化一组对象,是把 //所有要序列化的对象看作是一个对象数组来使用,在反序列化时一起读回来。 //下面是我对你的代码的改进。(使用的是序列和反序列化一组对象的方式!) //这也是在开发中最常见的一种方式!! class ObjectOutputStreamDemo { public static void main(String[] args) throws IOException, Exception { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt")); //把多个对象,存到对象数组中。 Person[] p = { new Person("张三", 20, "男"), new Person("王二", 20, "男"), new Person("李四", 24, "女") }; //序列化一组对象。 oos.writeObject(p); oos.flush(); oos.close(); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt")); //反序列化一组对象。 p = (Person[])ois.readObject(); //循环输出对象数组中的对象。 for(int i=0;i<p.length;i++){ System.out.println(p); } ois.close(); } } class Person implements Serializable{ private static final long serialVersionUID = 613659699548582156L; private String name; private int age; private String sex; public Person(String name, int age, String sex) { super(); this.name = name; this.age = age; this.sex = sex; } @Override public String toString() { //这里跟你上边写的toString是一样的,我这里写的代码好像跟什么东西,冲突了,显示一个笑脸!!!! return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } } |
在你的循环条件里 while((p = (Person)ois.readObject()) != null) 当所有对象都反序列化后 还会再执行一次对象读取操作 而这时 已经到了文件末尾 所以会报流到达文件尾异常 while((p = (Person)ois.readObject()) != null) { System.out.println(p); i++; if(i==3){ System.out.println(ois.read());//如果为-1 表示文件末尾 } } 你把循环里面的代码改成这样后 将会先打印-1 再报异常 打印-1表示 已经到达文件末尾 而后 你的循环又去读了一次文件 报了异常 这个异常对程序来说没多大影响 你可以利用这个异常来确定 反序列化已经结束 如果要避免这个异常 其实你可以将需要序列化的对象放到一个arraylist里面 然后序列化一次 反序列化的时候读取一次就行了 这样就不会报异常了 |