今天用ObjectOutputStream和ObjectInputStream进行对象序列化话操作的时候,报了java.io.EOFException异常。

异常代码如下:

  1. java.io.EOFException
  2. at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2554)
  3. at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1297)
  4. at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
  5. at cn.fuxi.io.ReadObject.readObject(ReadObject.java:27)
  6. 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

  1. import java.io.Serializable;
  2.  
  3. public class Person implements Serializable {
  4. /**
  5. *
  6. */
  7. private static final long serialVersionUID = -6374324573857634276L;
  8. private String name;
  9. private int age;
  10.  
  11. public Person(String name, int age) {
  12. this.name = name;
  13. this.age = age;
  14. }
  15.  
  16. public String getName() {
  17. return name;
  18. }
  19.  
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23.  
  24. public int getAge() {
  25. return age;
  26. }
  27.  
  28. public void setAge(int age) {
  29. this.age = age;
  30. }
  31.  
  32. }

2、写入对象的三种方法

  1. import java.io.FileOutputStream;
  2. import java.io.ObjectOutputStream;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. public class WriteObject {
  7.  
  8. /**
  9. * @param args
  10. */
  11. public static void main(String[] args) {
  12. writeObjectByArray();
  13. writeObject();
  14. writeObjectByList();
  15. }
  16. /**
  17. * 直接写入对象
  18. */
  19. private static void writeObject() {
  20. try {
  21. ObjectOutputStream oos = new ObjectOutputStream(
  22. new FileOutputStream("object.txt"));
  23. for (int i = 1; i < 10; i++) {
  24. oos.writeObject(new Person("欧阳鹏[" + i+"]", i));
  25. }
  26. //插入null是用来判断是否读取到结尾
  27. //写入结束标志方便读取(非常重要,如果不写入,在读取的时候无法定位读取结束);
  28. //读取的时候就会报 java.io.EOFException 异常
  29. oos.writeObject(null);
  30. oos.close();
  31. } catch (Exception e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. /**
  36. * 通过数组写入对象
  37. */
  38. private static void writeObjectByArray() {
  39. try {
  40. ObjectOutputStream oos = new ObjectOutputStream(
  41. new FileOutputStream("objectByArray.txt"));
  42. Person[] persons = new Person[10];
  43. for (int i = 1; i < 10; i++) {
  44. Person person = new Person("欧阳鹏 Arrays[" + (10+i)+"]", 10+i);
  45. persons[i] = person;
  46. }
  47. oos.writeObject(persons);
  48. oos.close();
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. /**
  54. * 通过集合写入对象
  55. */
  56. private static void writeObjectByList() {
  57. try {
  58. ObjectOutputStream oos = new ObjectOutputStream(
  59. new FileOutputStream("objectByList.txt"));
  60. List<Person> persons=new ArrayList<Person>();
  61. for (int i = 1; i < 10; i++) {
  62. Person person = new Person("欧阳鹏 List[" + (20+i)+"]", 20+i);
  63. persons.add(person);
  64. }
  65. //写入List
  66. oos.writeObject(persons);
  67. oos.close();
  68. } catch (Exception e) {
  69. e.printStackTrace();
  70. }
  71. }
  72.  
  73. }

3、读取对象的三种方法

  1. import java.io.FileInputStream;
  2. import java.io.ObjectInputStream;
  3. import java.util.List;
  4.  
  5. public class ReadObject {
  6. /**
  7. * @param args
  8. */
  9. public static void main(String[] args) {
  10. readObject();
  11. System.out.println("==============================");
  12. readObjectByArrays();
  13. System.out.println("==============================");
  14. readObjectByList();
  15. }
  16. /**
  17. * 直接读取对象
  18. */
  19. private static void readObject() {
  20. try {
  21. ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
  22. "object.txt"));
  23. Object obj = null;
  24. //如果为null就读取到文件结尾了
  25. //读取结束标志位:是再次读取一个对象,判定对象是否是空,如果不为null继续读取,如果为null停止读取
  26. while ((obj = ois.readObject()) != null) {
  27. ////反序列化读取得到Person
  28. Person person = (Person) obj;
  29. System.out.println("名字为:" + person.getName() + " 年龄为:"
  30. + person.getAge());
  31. }
  32. ois.close();
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. /**
  38. * 通过数组读取对象
  39. */
  40. private static void readObjectByArrays() {
  41. try {
  42. ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
  43. "objectByArray.txt"));
  44. //反序列化读取得到Person[]
  45. Person[] persons = (Person[]) ois.readObject();
  46. for (int i = 1; i < persons.length; i++) {
  47. Person person = (Person) persons[i];
  48. System.out.println("名字为:" + person.getName() + " 年龄为:"
  49. + person.getAge());
  50. }
  51. ois.close();
  52. } catch (Exception e) {
  53. e.printStackTrace();
  54. }
  55. }
  56. /**
  57. * 通过集合读取对象
  58. */
  59. private static void readObjectByList() {
  60. try {
  61. ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
  62. "objectByList.txt"));
  63. //反序列化读取得到List<Person>
  64. List<Person> persons = (List<Person>) ois.readObject();
  65. for (int i = 0; i <persons.size(); i++) {
  66. Person person=persons.get(i);
  67. System.out.println("名字为:" + person.getName() + " 年龄为:"
  68. + person.getAge());
  69. }
  70. ois.close();
  71. } catch (Exception e) {
  72. e.printStackTrace();
  73. }
  74. }
  75.  
  76. }

下面是结果:

写入对象后,在src同级目录下,生成3个文件,分别是object.txt 、objectByArray.txt、objectByList.txt   如下图所示。

读取对象,结果如下:

  1. 名字为:欧阳鹏[1] 年龄为:1
  2. 名字为:欧阳鹏[2] 年龄为:2
  3. 名字为:欧阳鹏[3] 年龄为:3
  4. 名字为:欧阳鹏[4] 年龄为:4
  5. 名字为:欧阳鹏[5] 年龄为:5
  6. 名字为:欧阳鹏[6] 年龄为:6
  7. 名字为:欧阳鹏[7] 年龄为:7
  8. 名字为:欧阳鹏[8] 年龄为:8
  9. 名字为:欧阳鹏[9] 年龄为:9
  10. ==============================
  11. 名字为:欧阳鹏 Arrays[11] 年龄为:11
  12. 名字为:欧阳鹏 Arrays[12] 年龄为:12
  13. 名字为:欧阳鹏 Arrays[13] 年龄为:13
  14. 名字为:欧阳鹏 Arrays[14] 年龄为:14
  15. 名字为:欧阳鹏 Arrays[15] 年龄为:15
  16. 名字为:欧阳鹏 Arrays[16] 年龄为:16
  17. 名字为:欧阳鹏 Arrays[17] 年龄为:17
  18. 名字为:欧阳鹏 Arrays[18] 年龄为:18
  19. 名字为:欧阳鹏 Arrays[19] 年龄为:19
  20. ==============================
  21. 名字为:欧阳鹏 List[21] 年龄为:21
  22. 名字为:欧阳鹏 List[22] 年龄为:22
  23. 名字为:欧阳鹏 List[23] 年龄为:23
  24. 名字为:欧阳鹏 List[24] 年龄为:24
  25. 名字为:欧阳鹏 List[25] 年龄为:25
  26. 名字为:欧阳鹏 List[26] 年龄为:26
  27. 名字为:欧阳鹏 List[27] 年龄为:27
  28. 名字为:欧阳鹏 List[28] 年龄为:28
  29. 名字为:欧阳鹏 List[29] 年龄为:29

==================================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址:http://blog.csdn.net/ouyang_peng

==================================================================================================

判断ObjectInputStream是否读到文件末尾,文件长度未知

判断ObjectInputStream是否读到文件末尾,文件长度未知

判断ObjectInputStream是否读到文件末尾,文件长度未知

我的Java开发学习之旅------>Java使用ObjectOutputStream和ObjectInputStream序列号对象报java.io.EOFException异常的解决方法的更多相关文章

  1. 我的Java开发学习之旅------>Java 格式化类(java.util.Formatter)基本用法

    本文参考: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html http://www.blogjava.net/ ...

  2. 我的Java开发学习之旅------>工具类:将播放器的进度值转换成相应的时间格式

    在我的博客<我的Java开发学习之旅------>Java 格式化类(java.util.Formatter)基本用法,地址:http://blog.csdn.net/ouyang_pen ...

  3. 我的Java开发学习之旅------>在Dos环境下Java内部类的编译和运行

    习惯了在IDE工具上进行代码编写,连最基本的Javac命令和Java命令都忘记的差不多了,今天对一个Java内部类进行编译和运行的时候,就出糗了.IDE是把双刃剑,它可以什么都帮你做了,你只要敲几行代 ...

  4. 我的Java开发学习之旅------>Java NIO 报java.nio.charset.MalformedInputException: Input length = 1异常

    今天在使用Java NIO的Channel和Buffer进行文件操作时候,报了java.nio.charset.MalformedInputException: Input length = 1异常, ...

  5. 我的Java开发学习之旅------>Java语言中方法的参数传递机制

    实参:如果声明方法时包含来了形参声明,则调用方法时必须给这些形参指定参数值,调用方法时传给形参的参数值也被称为实参. Java的实参值是如何传入方法?这是由Java方法的参数传递机制来控制的,Java ...

  6. 我的Java开发学习之旅------>工具类:Java获取字符串和文件进行MD5值

    ps:这几天本人用百度云盘秒传了几部大片到云盘上,几个G的文件瞬秒竟然显示"上传成功"!这真让我目瞪口呆,要是这样的话,那得多快的网速,这绝对是不可能的,也许这仅是个假象.百度了一 ...

  7. 我的Java开发学习之旅------>工具类:Java使用正则表达式分离出字符串中的中文和英文

    今天看到一个工具类使用正则表达式将一大段字符串中的中文和英文都分离出来了,在此记录一下,读者可以收藏! import java.util.ArrayList; import java.util.Col ...

  8. 我的Java开发学习之旅------&gt;Base64的编码思想以及Java实现

    Base64是一种用64个字符来表示随意二进制数据的方法. 用记事本打开exe.jpg.pdf这些文件时,我们都会看到一大堆乱码,由于二进制文件包括非常多无法显示和打印的字符.所以,假设要让记事本这种 ...

  9. 我的Java开发学习之旅------>Java利用Comparator接口对多个排序条件进行处理

    一需求 二实现Comparator接口 三验证排序结果 验证第一条件首先按级别排序级别最高的排在前面 验证第二条如果级别相等那么按工资排序工资高的排在前面 验证第三条如果工资相当则按入职年数排序入职时 ...

随机推荐

  1. bzoj 1571: [Usaco2009 Open]滑雪课

    http://www.lydsy.com/JudgeOnline/problem.php?id=1571 dp[i][j]表示前i个时间,能力为j所能达到得最大滑雪次数 预处理出,需要能力$<= ...

  2. Graphs (Cakewalk) 1 B - medium

    Discription Bear Limak examines a social network. Its main functionality is that two members can bec ...

  3. php类中静态变量与常亮的区别

    在效率上:常量编译过程比静态变量快的多. 代码: <?php error_reporting(E_ALL); class A { const c = 9; public static $b = ...

  4. OFV.msi是什么 为什么更新时无法安装

    在网络上搜索了下 这个是Microsoft Office 文件验证加载项,微软提供了一个单独的文件:http://www.microsoft.com/downloads/zh-cn/confirmat ...

  5. git-ssh配置和使用

    https://segmentfault.com/a/1190000002645623 1.设置Git的user name和email:(如果是第一次的话) $ git config --global ...

  6. FTP经典常用命令

    FTP命令是Internet用户使用最频繁的命令之一,不论是在DOS还是UNIX操作系统下使用FTP,都会遇到大量的FTP内部命令. 熟悉并灵活应用FTP的内部命令,可以大大方便使用者,并收到事半功倍 ...

  7. LeetCode 290 Word Pattern(单词模式)(istringstream、vector、map)(*)

    翻译 给定一个模式,和一个字符串str.返回str是否符合同样的模式. 这里的符合意味着全然的匹配,所以这是一个一对多的映射,在pattern中是一个字母.在str中是一个为空的单词. 比如: pat ...

  8. Linux USB驱动数据结构

    struct usb_ctrlrequest {    __u8 bRequestType;    __u8 bRequest;    __le16 wValue;    __le16 wIndex; ...

  9. C++课程资源下载问题

    [来信] 贺老师,您好,我是江西某高校软件学院的一名在校学生.看了您在csdn上公布的博文和视频,我获益良多.不得不承认,之前的大学时光我是荒废了,立即就要大三了,我主攻的是C++方面.因此我悔过自新 ...

  10. solor5.4学习笔记

    1.下载地址:http://archive.apache.org/dist/lucene/solr/ 2.与tomcat的整合http://jingyan.baidu.com/article/d807 ...