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

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

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

这是一个IO异常的子类,名字也是END OF FILE的缩写,当然也表示流的末尾

它在表明一个信息,流已经到末尾了,而大部分做法是以特殊值的形式返回给我们,而不是抛异常

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

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

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

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

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

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

packageyiwangzhibujian.objectstream;

importjava.io.ByteArrayInputStream;

importjava.io.ByteArrayOutputStream;

importjava.io.ObjectInputStream;

importjava.io.ObjectOutputStream;

importjava.io.Serializable;

public classObjectStream {

public static void main(String[] args) throwsException {

User user1=new User("yiwangzhibujian",27);

User user2=new User("laizhezhikezhui",24);

ByteArrayOutputStream bos=newByteArrayOutputStream();

ObjectOutputStream oos=newObjectOutputStream(bos);

oos.writeObject(user1);

oos.writeObject(user2);

oos.writeObject(null);

byte[] data =bos.toByteArray();

ByteArrayInputStream bis=newByteArrayInputStream(data);

ObjectInputStream ois=newObjectInputStream(bis);

System.out.println(ois.readObject());

System.out.println(ois.readObject());

System.out.println(ois.readObject());

System.out.println(ois.readObject());

}

}

class User implementsSerializable{

private static final long serialVersionUID = 1L;

publicString name;

public intage;

public User(String name, intage) {

this.name =name;

this.age =age;

}

@Override

publicString toString() {

return "User [name=" + name + ", age=" + age + "]";

}

}

控制台输出结果为:

User [name=yiwangzhibujian, age=27]

User [name=laizhezhikezhui, age=24]

nullException 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() throwsIOException {

int val =peek();

if (val < 0) {

throw newEOFException();

}

return (byte) val;

}

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

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

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

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

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

需求:  *1、创建54张扑克牌,将扑克牌写入文件card.txt  *2、将写入的文件内容,读取出来,可以生成相对应的54张扑克牌  *3、保证扑克牌可以调用自己的方法

遇到的问题以及解决方法:

1.序列化的问题:你要创建的对象在流中传输,必须将此类对象进行序列化,就是implements Serializable接口

2.EOFException的问题: 你从文件中读取对象的时候,如何判断是否读取完毕。jvm会给抛出EOFException,表示的是,文件中对象读取完毕。所以呢,你在判断是否读取结束的时候,捕获掉这个异常就可以,是捕获不是抛出。

重要的说三次,是捕获,捕获,捕获!

代码如下:

package day02;

import java.io.EOFException;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.util.ArrayList;

import java.util.List;

/**

*1、创建54张扑克牌,将扑克牌写入文件card.txt

*2、将写入的文件内容,读取出来,可以生成相对应的54张扑克牌

*3、保证扑克牌可以调用自己的方法

*/

public class Exercis {

public static void main(String[] args) throws FileNotFoundException, IOException {

ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream(new File("./card.txt")));

List lists=new ArrayList();

for(int i=Card.THREE;i<=Card.TWO;i++){

lists.add(new Card(Card.HEITAO,i));

lists.add(new Card(Card.HONGTAO,i));

lists.add(new Card(Card.MEIHUA,i));

lists.add(new Card(Card.FANGKUAI,i));

}

lists.add(new Card(Card.JOKER,Card.BLACK));

lists.add(new Card(Card.JOKER,Card.COLOR));

for(Card c : lists){

os.writeObject(c);

}

ObjectInputStream is=new ObjectInputStream(new FileInputStream(new File("./card.txt")));

while(true){

Object o = null;

try {

o = is.readObject();

if(o instanceof Card){

System.out.println(o);

}

} catch (ClassNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}catch(EOFException e){

System.out.println("读写完毕!");

os.close();

is.close();

break;

}

}

}

}

java eofexception_EOFException异常详解相关推荐

  1. JAVA基础——异常详解

    阅读目录 一.异常简介 二.try-catch-finally语句 三.throw和throws关键字 四.java中的异常链 五.结束语 JAVA异常与异常处理详解 回到顶部 一.异常简介 什么是异 ...

  2. java(22) - 异常详解

    一.异常(Exception): 所谓的异常就是程序运行时可能出现的一些错误,但并不是所有的错误都是异常,并且有些错误是可以避免的,像敲打代码时你少敲了一个分号,那么运行出来的结果错误java.lan ...

  3. 【Java】“异常”详解

    Java异常目录: 1.异常定义 2.异常的用法 2.1捕获异常 2.2 调用栈 定义 2.3 其他一些注意事项 3.异常处理流程 4. 抛出异常 5.异常说明 6. Java 异常体系 7.自定义异 ...

  4. Java异常详解及如何处理

    来源:Java异常详解及如何处理 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言 ...

  5. Java内存溢出详解之Tomcat配置

    Java内存溢出详解 转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError ...

  6. Java内存溢出详解

    Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 JVM在 ...

  7. 4.6 W 字总结!Java 11—Java 17特性详解

    作者 | 民工哥技术之路 来源 | https://mp.weixin.qq.com/s/SVleHYFQeePNT7q67UoL4Q Java 11 特性详解 基于嵌套的访问控制 与 Java 语言 ...

  8. 代码检查规则:Java语言案例详解

    本节课程为<代码检查规则:Java语言案例详解>, 通常情况下Java的代码检查规则可以分为以下十类: 接下来,让我们具体来看看每个分类的内容. 一.源文件规范 该类规范主要从文件名.文件 ...

  9. java多线程学习-java.util.concurrent详解

    http://janeky.iteye.com/category/124727 java多线程学习-java.util.concurrent详解(一) Latch/Barrier 博客分类: java ...

  10. 5W字高质量java并发系列详解教程(上)-附PDF下载

    文章目录 第一章 java.util.concurrent简介 主要的组件 Executor ExecutorService ScheduledExecutorService Future Count ...

最新文章

  1. 今年的谷歌I/O大会,或许会有这些东西
  2. Spark机器学习9· 实时机器学习(scala with sbt)
  3. mysql服务器消失_MySQL服务器已经消失了
  4. 2019.05.15
  5. Nacos配置中心介绍
  6. win7无法连接打印机拒绝访问_Win7系统”windows无法连接到打印机拒绝访问“怎么办?通过创建local port端口连接来搞定...
  7. 李洋疯狂C语言之关于自增自减遇到的一些问题
  8. ios10中禁止Safari浏览器用户缩放页面
  9. 常见iPhone设备尺寸及分辨率(持续更新)
  10. CF991C Candies
  11. c语言线程原理,线程池的原理和实现c语言
  12. c语言程序怎样缩进整体,C语言程序设计基础概念
  13. MATLAB人脸识别区域定位实战源码解析
  14. win7怎么关uac_win7电脑如何关闭uac用户账户控制
  15. ubuntu下安装万能五笔
  16. 讯飞语音合成 如何选择发音人
  17. tsconfig之include和exclude详解
  18. 盛世昊通全新升级,引领智慧新经济
  19. vim配置set nu
  20. 【项目总结】论文复现与改进:一般选择模型的产品组合优化算法(Research@收益管理)

热门文章

  1. 暴力猴插件的安装及使用
  2. 华为手机计算机不能用,华为手机无法连接电脑(手机助手)怎么办,连接不上...
  3. 基于Android的家庭财务管理流程图,基于android的个人财务管理系统的设计与实现.pdf...
  4. 勒索病毒:解密工具整理
  5. TendaU12无线网卡Linux驱动,解决Centos7 安装腾达U12无线网卡驱动问题
  6. 千图成像python_爬取英雄联盟所有皮肤图片实现千图成像~
  7. ERP : 服装行业解决方案
  8. Java docx4j 操作word 1.0
  9. 笔记 时间2012年2月15日14:35:30
  10. 课程设计 - 运动控制卡(云服务器)