java eofexception_EOFException异常详解
最近线上的系统被检测出有错误日志,领导让我检查下问题,我就顺便了解了下这个异常。
了解一个类,当然是先去看他的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异常详解相关推荐
- JAVA基础——异常详解
阅读目录 一.异常简介 二.try-catch-finally语句 三.throw和throws关键字 四.java中的异常链 五.结束语 JAVA异常与异常处理详解 回到顶部 一.异常简介 什么是异 ...
- java(22) - 异常详解
一.异常(Exception): 所谓的异常就是程序运行时可能出现的一些错误,但并不是所有的错误都是异常,并且有些错误是可以避免的,像敲打代码时你少敲了一个分号,那么运行出来的结果错误java.lan ...
- 【Java】“异常”详解
Java异常目录: 1.异常定义 2.异常的用法 2.1捕获异常 2.2 调用栈 定义 2.3 其他一些注意事项 3.异常处理流程 4. 抛出异常 5.异常说明 6. Java 异常体系 7.自定义异 ...
- Java异常详解及如何处理
来源:Java异常详解及如何处理 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言 ...
- Java内存溢出详解之Tomcat配置
Java内存溢出详解 转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError ...
- Java内存溢出详解
Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 JVM在 ...
- 4.6 W 字总结!Java 11—Java 17特性详解
作者 | 民工哥技术之路 来源 | https://mp.weixin.qq.com/s/SVleHYFQeePNT7q67UoL4Q Java 11 特性详解 基于嵌套的访问控制 与 Java 语言 ...
- 代码检查规则:Java语言案例详解
本节课程为<代码检查规则:Java语言案例详解>, 通常情况下Java的代码检查规则可以分为以下十类: 接下来,让我们具体来看看每个分类的内容. 一.源文件规范 该类规范主要从文件名.文件 ...
- java多线程学习-java.util.concurrent详解
http://janeky.iteye.com/category/124727 java多线程学习-java.util.concurrent详解(一) Latch/Barrier 博客分类: java ...
- 5W字高质量java并发系列详解教程(上)-附PDF下载
文章目录 第一章 java.util.concurrent简介 主要的组件 Executor ExecutorService ScheduledExecutorService Future Count ...
最新文章
- 今年的谷歌I/O大会,或许会有这些东西
- Spark机器学习9· 实时机器学习(scala with sbt)
- mysql服务器消失_MySQL服务器已经消失了
- 2019.05.15
- Nacos配置中心介绍
- win7无法连接打印机拒绝访问_Win7系统”windows无法连接到打印机拒绝访问“怎么办?通过创建local port端口连接来搞定...
- 李洋疯狂C语言之关于自增自减遇到的一些问题
- ios10中禁止Safari浏览器用户缩放页面
- 常见iPhone设备尺寸及分辨率(持续更新)
- CF991C Candies
- c语言线程原理,线程池的原理和实现c语言
- c语言程序怎样缩进整体,C语言程序设计基础概念
- MATLAB人脸识别区域定位实战源码解析
- win7怎么关uac_win7电脑如何关闭uac用户账户控制
- ubuntu下安装万能五笔
- 讯飞语音合成 如何选择发音人
- tsconfig之include和exclude详解
- 盛世昊通全新升级,引领智慧新经济
- vim配置set nu
- 【项目总结】论文复现与改进:一般选择模型的产品组合优化算法(Research@收益管理)
热门文章
- 暴力猴插件的安装及使用
- 华为手机计算机不能用,华为手机无法连接电脑(手机助手)怎么办,连接不上...
- 基于Android的家庭财务管理流程图,基于android的个人财务管理系统的设计与实现.pdf...
- 勒索病毒:解密工具整理
- TendaU12无线网卡Linux驱动,解决Centos7 安装腾达U12无线网卡驱动问题
- 千图成像python_爬取英雄联盟所有皮肤图片实现千图成像~
- ERP : 服装行业解决方案
- Java docx4j 操作word 1.0
- 笔记 时间2012年2月15日14:35:30
- 课程设计 - 运动控制卡(云服务器)