最近线上的系统被检测出有错误日志,领导让我检查下问题,我就顺便了解了下这个异常。

  了解一个类,当然是先去看他的API,EOFException的API如下:

  通过这个API,我们可以得出以下信息:

  • 这是一个IO异常的子类,名字也是END OF FILE的缩写,当然也表示流的末尾
  • 它在表明一个信息,流已经到末尾了,而大部分做法是以特殊值的形式返回给我们,而不是抛异常

  也就是说这个异常是被主动抛出来的,而不是底层或者编译器返回给我的,就像NullPointerException或IndexOutOfBoundsException一样。

  我们先来看InputStream,这个输入流,当读到了结尾会怎么样,看看API介绍:

  可以看到如果到达流的末尾,那么会返回-1,也就是说我们可以根据这个-1来判断是否到达流的末尾。

  同样的我们看一下输入流的包装类BufferedReader,它有一个读一行的方法:

  也可以发现当读到流的末尾,通过返回值null来告诉我们到达流的末尾了,也就是说通过返回一个不可能的值来表示到达流的末尾。

  那我们找一个EOFException的例子,在jdk类中就有一个,那就是ObjectInputStream,我写了一个测试代码,如下:

package yiwangzhibujian.objectstream;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable; public class ObjectStream {
public static void main(String[] args) throws Exception {
User user1=new User("yiwangzhibujian",27);
User user2=new User("laizhezhikezhui",24); ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos); oos.writeObject(user1);
oos.writeObject(user2);
oos.writeObject(null); byte[] data = bos.toByteArray();
ByteArrayInputStream bis=new ByteArrayInputStream(data);
ObjectInputStream ois=new ObjectInputStream(bis); System.out.println(ois.readObject());
System.out.println(ois.readObject());
System.out.println(ois.readObject());
System.out.println(ois.readObject());
}
}
class User implements Serializable{
private static final long serialVersionUID = 1L;
public String name;
public int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}

  控制台输出结果为:

User [name=yiwangzhibujian, age=27]
User [name=laizhezhikezhui, age=24]
null
Exception in thread "main" java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2608)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1319)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at yiwangzhibujian.objectstream.ObjectStream.main(ObjectStream.java:28)

  可以感觉到EOFException的用意,因为我们可以往流中放入null值,所以我们没法找到一个不可能的值来表示到达流的末尾,所以只能通过抛异常的方式来告诉用户到达末尾了,相应的抛异常部分的源码如下:

byte peekByte() throws IOException {
int val = peek();
if (val < 0) {
throw new EOFException();
}
return (byte) val;
}

  也就是说,ObjectInputStream在读取具体的对象之前会优先读取一个标识符,它通过是否能读到符号来判断是否到达流的末尾,因为再底层的流会通过返回-1来表明,然后ObjectInputStream会根据标识符来判断读到的是什么类型,因为ObjectOutputStream 在写入内容的时候会这么做:

  所以说ObjectInputStream可以自己判断流是否到达末尾,但是它无法告诉我们,我们不能替代他们读取这个标记,不然ObjectInputStream将识别不了下一个内容的实际类型。

  所以呢,对于这种异常的一般解决方法就是,捕获,可以记录日志,也可以不做处理,捕获异常以后,把之前读到的数据进行后续的处理就可以了,因为那就是所以的数据。还有就是如果打算记录日志,不要把它的堆栈信息打印出来,容易给人以错觉。毕竟EOFException实质上只是一个消息而已。

  当然抛异常的做法还是有一些偏激,但是当ObjectInputStream在不知道读取对象数量的情况下,确实无法判断是否读完,除非你把之前写入对象流的数量记录下来。所以说出现这个异常时就认真分析一下,这个异常是不是代表一个信息。

  希望我对这个问题的理解,能帮助到遇到同样问题的人。

  

【疑难杂症04】EOFException异常详解的更多相关文章

  1. EOFException异常详解

    最近线上的系统被检测出有错误日志,领导让我检查下问题,我就顺便了解了下这个异常. 了解一个类,当然是先去看他的API,EOFException的API如下: 通过这个API,我们可以得出以下信息: 这 ...

  2. JAVA基础——异常详解

    JAVA异常与异常处理详解 一.异常简介 什么是异常? 异常就是有异于常态,和正常情况不一样,有错误出错.在java中,阻止当前方法或作用域的情况,称之为异常. java中异常的体系是怎么样的呢? 1 ...

  3. java基础(十五)----- Java 最全异常详解 ——Java高级开发必须懂的

    本文将详解java中的异常和异常处理机制 异常简介 什么是异常? 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常. Java异常的分类和类结构图 1.Java中的所 ...

  4. TeamViewer的下载、安装和使用(windows7、CentOS6.5和Ubuntu14.04(64bit))(图文详解)

    不多说,直接上干货! TeamViewr是远程支持.远程访问.在线协作和会议软件. 分为从windows7.CentOS6.5和Ubuntu14.04(64bit) 系统来详解下载.安装和初步使用! ...

  5. Java面向对象之异常详解

    目录 Java面向对象之异常[一] Java面向对象之异常[二] 捕获异常的规则 访问异常信息 异常对方法重写的影响 finally详解 Java面向对象之异常[一] Java面向对象之异常[二] 往 ...

  6. cpp异常详解

    1. 异常介绍 在函数在执行过程中如果碰到对错误的处理可以有两种方式, 1. 返回错误,2. 使用异常. 如果作为函数的调用者想要知道具体的错误信息, 就需要维护一套错误列表, 或者用string类型 ...

  7. Java基础 - 异常详解

    异常的层次结构 Throwable Throwable 是 Java 语言中所有错误与异常的超类. Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示 ...

  8. Webwork 学习之路【04】Configuration 详解

    Webwork做为经典的Web MVC 框架,个人觉得源码中配置文件这部分代码的实现十分考究. 支持自定义自己的配置文件.自定义配置文件读取类.自定义国际化支持. 可以作为参考,单独引入到其他项目中, ...

  9. java笔记--异常详解与处理

    一.异常概念 Throwable类是Java中所有错误或异常的超类. 1.只有当对象是此类(或其子类)的实例时,才能通过Java虚拟机或着Java throw语句抛出.     2.只有此类或其子类才 ...

随机推荐

  1. 安装eclipse启动时报错

    1.在安装eclipse后,点击exe文件时,提示出现错误,记录在log文件中,因为log文件就是日志文件,可以方便我们排查错误,打开log文件,可以看到文件记录了每次出错的时间和错误栈信息,最新一次 ...

  2. Java之ServiceLoader

    转载请注明源出处:http://www.cnblogs.com/lighten/p/6946683.html 1.简介 JDK1.6之后,java.util包下多了一个类ServiceLoader,其 ...

  3. android app性能优化大汇总

    这里根据网络上各位大神已经总结的知识内容做一个大汇总,作为记录,方便后续“温故知新”. 性能指标: (1)使用流畅度:  图片处理器每秒刷新的帧数(FPS),可用来指示页面是否平滑的渲染.高的帧率可以 ...

  4. Web Components实践开发Tab组件

    本文是对web components的一次实践,最终目的是做出一个tab组件,本文涉及Custom Elements(自定义元素).HTML Imports(HTML导入).HTML Template ...

  5. vim中使用系统粘贴板

    在vim中如果想使用系统粘贴板,也就是说,如果你在其他程序中复制内容,那么使用shift+insert组合键就可以粘贴进来. 需要说明的是,vim中的粘贴板有很多,你可以输入 :reg来进行查看.而我 ...

  6. Python虚拟环境工具-Virtualenv 介绍及部署记录

    在开发Python应用程序时,系统默认的Python版本可能会不兼容这个应用程序, 如果同时开发多个应用程序, 可能会用到好几个版本的python环境, 这种情况下,每个应用可能需要各自拥有一套&qu ...

  7. mysql进行时

    1. 安装 参考 2. 远程连不上数据库 远程连接mysql时,提示“is not allowed to connect to this MySQL server” 解决(授权法): GRANT AL ...

  8. 导入maven项目遇到中文乱码

    windows->preferences->content types->word Document 并输入utf-8->update; 右键选中的项目,选择propertie ...

  9. [转]史上最佳 Mac+PhpStorm+XAMPP+Xdebug 集成开发和断点调试环境的配置

    本文转自:https://www.cnblogs.com/lishiyun19/p/4470086.html 在上一篇 PHP 系列的文章<PHP 集成开发环境比较>中,我根据自己的亲身体 ...

  10. Connect the Cities(hdu3371)并查集(附测试数据)

    Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...