今天用ObjectOutputStream和ObjectInputStream进行对象序列化话操作的时候,报了java.io.EOFException异常。
异常代码如下:
java.io.EOFException at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2554) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) at cn.fuxi.io.ReadObject.readObject(ReadObject.java:27) at cn.fuxi.io.ReadObject.main(ReadObject.java:12)这个异常是因为我使用 ObjectInputStream读取对象时候,没有判断好ObjectInputStream是否读取到了未知长度的文件末尾,导致到了文件末尾,程序无法正常读取文件内容。
后来研究了一下以后,得出三种解救思路:
第一种方法:
在写完对象后,加一句 oos.writeObject(null); 插入null是用来判断是否读取到结尾。oos是ObjectOutputStream实例。
然后读对象的时候,使用while ((obj = ois.readObject()) != null),来判断再次读取一个对象,判定对象是否是空,如果不为null继续读取,如果为null停止读取。
第二种方法:
将若干个对象(数量不定)都装入 一个容器中(如:ArrayList之类的),然后写对象的时候,将该容器写入。
读取的时候,读取出容器,然后再遍历容器,取出自己所需的对象。
第三个方法:
和第二个方法类似,将对象都存入数组中,然后写入数组对象。
读取的时候,取出数组,再遍历数组,取出所需的对象。
下面是具体的代码操作:
1、要进行序列号的对象 Person.java
import java.io.Serializable; public class Person implements Serializable { /** * */ private static final long serialVersionUID = -6374324573857634276L; private String name; private int age; public Person(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; } }
2、写入对象的三种方法
import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; public class WriteObject { /** * @param args */ public static void main(String[] args) { writeObjectByArray(); writeObject(); writeObjectByList(); } /** * 直接写入对象 */ private static void writeObject() { try { ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("object.txt")); for (int i = 1; i < 10; i++) { oos.writeObject(new Person("欧阳鹏[" + i+"]", i)); } //插入null是用来判断是否读取到结尾 //写入结束标志方便读取(非常重要,如果不写入,在读取的时候无法定位读取结束); //读取的时候就会报 java.io.EOFException 异常 oos.writeObject(null); oos.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 通过数组写入对象 */ private static void writeObjectByArray() { try { ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("objectByArray.txt")); Person[] persons = new Person[10]; for (int i = 1; i < 10; i++) { Person person = new Person("欧阳鹏 Arrays[" + (10+i)+"]", 10+i); persons[i] = person; } oos.writeObject(persons); oos.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 通过集合写入对象 */ private static void writeObjectByList() { try { ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("objectByList.txt")); List<Person> persons=new ArrayList<Person>(); for (int i = 1; i < 10; i++) { Person person = new Person("欧阳鹏 List[" + (20+i)+"]", 20+i); persons.add(person); } //写入List oos.writeObject(persons); oos.close(); } catch (Exception e) { e.printStackTrace(); } } }
import java.io.FileInputStream; import java.io.ObjectInputStream; import java.util.List; public class ReadObject { /** * @param args */ public static void main(String[] args) { readObject(); System.out.println("=============================="); readObjectByArrays(); System.out.println("=============================="); readObjectByList(); } /** * 直接读取对象 */ private static void readObject() { try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream( "object.txt")); Object obj = null; //如果为null就读取到文件结尾了 //读取结束标志位:是再次读取一个对象,判定对象是否是空,如果不为null继续读取,如果为null停止读取 while ((obj = ois.readObject()) != null) { ////反序列化读取得到Person Person person = (Person) obj; System.out.println("名字为:" + person.getName() + " 年龄为:" + person.getAge()); } ois.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 通过数组读取对象 */ private static void readObjectByArrays() { try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream( "objectByArray.txt")); //反序列化读取得到Person[] Person[] persons = (Person[]) ois.readObject(); for (int i = 1; i < persons.length; i++) { Person person = (Person) persons[i]; System.out.println("名字为:" + person.getName() + " 年龄为:" + person.getAge()); } ois.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 通过集合读取对象 */ private static void readObjectByList() { try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream( "objectByList.txt")); //反序列化读取得到List<Person> List<Person> persons = (List<Person>) ois.readObject(); for (int i = 0; i <persons.size(); i++) { Person person=persons.get(i); System.out.println("名字为:" + person.getName() + " 年龄为:" + person.getAge()); } ois.close(); } catch (Exception e) { e.printStackTrace(); } } }
下面是结果:
写入对象后,在src同级目录下,生成3个文件,分别是object.txt 、objectByArray.txt、objectByList.txt 如下图所示。
读取对象,结果如下:
名字为:欧阳鹏[1] 年龄为:1 名字为:欧阳鹏[2] 年龄为:2 名字为:欧阳鹏[3] 年龄为:3 名字为:欧阳鹏[4] 年龄为:4 名字为:欧阳鹏[5] 年龄为:5 名字为:欧阳鹏[6] 年龄为:6 名字为:欧阳鹏[7] 年龄为:7 名字为:欧阳鹏[8] 年龄为:8 名字为:欧阳鹏[9] 年龄为:9 ============================== 名字为:欧阳鹏 Arrays[11] 年龄为:11 名字为:欧阳鹏 Arrays[12] 年龄为:12 名字为:欧阳鹏 Arrays[13] 年龄为:13 名字为:欧阳鹏 Arrays[14] 年龄为:14 名字为:欧阳鹏 Arrays[15] 年龄为:15 名字为:欧阳鹏 Arrays[16] 年龄为:16 名字为:欧阳鹏 Arrays[17] 年龄为:17 名字为:欧阳鹏 Arrays[18] 年龄为:18 名字为:欧阳鹏 Arrays[19] 年龄为:19 ============================== 名字为:欧阳鹏 List[21] 年龄为:21 名字为:欧阳鹏 List[22] 年龄为:22 名字为:欧阳鹏 List[23] 年龄为:23 名字为:欧阳鹏 List[24] 年龄为:24 名字为:欧阳鹏 List[25] 年龄为:25 名字为:欧阳鹏 List[26] 年龄为:26 名字为:欧阳鹏 List[27] 年龄为:27 名字为:欧阳鹏 List[28] 年龄为:28 名字为:欧阳鹏 List[29] 年龄为:29
==================================================================================================
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng
==================================================================================================