Java IO: 异常处理

原文链接 作者:Jakob Jenkov 译者: 李璟([email protected])

流与Reader和Writer在结束使用的时候,需要正确地关闭它们。通过调用close()方法可以达到这一点。不过这需要一些思考。请看下边的代码:

01 InputStream input = new FileInputStream("c:\\data\\input-text.txt");
02  
03 int data = input.read();
04  
05 while(data != -1) {
06  
07     //do something with data...  
08  
09     doSomethingWithData(data);
10  
11     data = input.read();
12  
13 }
14  
15 input.close();

第一眼看这段代码时,可能觉得没什么问题。可是如果在调用doSomethingWithData()方法时出现了异常,会发生什么呢?没错,这个InputStream对象就不会被关闭。

为了避免异常造成流无法被关闭,我们可以把代码重写成这样:

01 InputStream input = null;
02  
03 try{
04  
05     input = new FileInputStream("c:\\data\\input-text.txt");
06  
07     int data = input.read();
08  
09     while(data != -1) {
10  
11         //do something with data...
12  
13         doSomethingWithData(data);
14  
15         data = input.read();
16  
17 }
18  
19 }catch(IOException e){
20  
21     //do something with e... log, perhaps rethrow etc.
22  
23 finally {
24  
25     if(input != null)
26  
27         input.close();
28  
29 }

注意到这里把InputStream的关闭代码放到了finally块中,无论在try-catch块中发生了什么,finally内的代码始终会被执行,所以这个InputStream总是会被关闭。

但是如果close()方法抛出了异常,告诉你流已经被关闭过了呢?为了解决这个难题,你也需要把close()方法写在try-catch内部,就像这样:

01 finally {
02  
03     try{
04  
05         if(input != null)
06  
07             input.close();
08  
09     catch(IOException e){
10  
11         //do something, or ignore.
12  
13     }
14 }

这段解决了InputStream(或者OutputStream)流关闭的问题的代码,确实是有一些不优雅,尽管能够正确处理异常。如果你的代码中重复地遍布了这段丑陋的异常处理代码,这不是很好的一个解决方案。如果一个匆忙的家伙贪图方便忽略了异常处理呢?

此外,想象一下某个异常最先从doSomethingWithData方法内抛出。第一个catch会捕获到异常,然后在finally里程序会尝试关闭InputStream。但是如果还有异常从close()方法内抛出呢?这两个异常中得哪个异常应当往调用栈上传播呢?

幸运的是,有一个办法能够解决这个问题。这个解决方案称作“异常处理模板”。创建一个正确关闭流的模板,能够在代码中做到一次编写,重复使用,既优雅又简单。详情参见Java异常处理模板

Java7中IO的异常处理

从Java7开始,一种新的被称作“try-with-resource”的异常处理机制被引入进来。这种机制旨在解决针对InputStream和OutputStream这类在使用完毕之后需要关闭的资源的异常处理。可以浏览Try with Resource in Java 7获得更多信息。

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: Java IO: 异常处理

时间: 2024-10-14 12:31:26

Java IO: 异常处理的相关文章

Java IO: ByteArray和Filter

作者: Jakob Jenkov 译者: 李璟([email protected]) 本小节会简要概括Java IO中字节数组与过滤器的输入输出流,主要涉及以下4个类型的流:ByteArrayInputStream,ByteArrayOutputStream,FilterInputStream,FilterOutputStream.请注意,为了清晰,这里忽略了必要的异常处理.想了解更多异常处理的信息,请参考Java IO异常处理. ByteArrayInputStream 原文链接 ByteAr

Java IO: InputStreamReader和OutputStreamWriter

作者: Jakob Jenkov 译者: 李璟([email protected]) 本章节将简要介绍InputStreamReader和OutputStreamWriter.细心的读者可能会发现,在之前的文章中,IO中的类要么以Stream结尾,要么以Reader或者Writer结尾,那这两个同时以字节流和字符流的类名后缀结尾的类是什么用途呢?简单来说,这两个类把字节流转换成字符流,中间做了数据的转换,类似适配器模式的思想. InputStreamReader 原文链接 InputStream

Java IO: InputStream

原文链接 作者: Jakob Jenkov 译者: 李璟([email protected]) InputStream类是Java IO API中所有输入流的基类.InputStream子类包括FileInputStream,BufferedInputStream,PushbackInputStream等等.参考Java IO概述这一小节底部的表格,可以浏览完整的InputStream子类的列表. Java InputStream例子 InputStream用于读取基于字节的数据,一次读取一个字

Java IO: PipedInputStream

原文链接 作者: Jakob Jenkov 译者: 李璟([email protected]) PipedInputStream可以从管道中读取字节流数据,代码如下: 01 InputStream input = new PipedInputStream(pipedOutputStream); 02   03 int data = input.read(); 04   05 while(data != -1) { 06   07     //do something with data... 0

Java IO: OutputStream

原文链接 作者: Jakob Jenkov 译者: 李璟([email protected]) OutputStream类是Java IO API中所有输出流的基类.子类包括BufferedOutputStream,FileOutputStream等等.参考Java IO概述这一小节底部的表格,可以浏览完整的子类的列表. 输出流和目标媒介 输出流往往和某些数据的目标媒介相关联,比如文件,网络连接,管道等.更多细节请参考Java IO概述.当写入到输出流的数据逐渐输出完毕时,目标媒介是所有数据的归

Java IO: FileOutputStream

原文链接 作者: Jakob Jenkov 译者: 李璟([email protected]) FileOutputStream可以往文件里写入字节流,它是OutputStream的子类,所以你可以像使用OutputStream那样使用FileOutputStream. 这是一个FileOutputStream的例子: 01 OutputStream output = new FileOutputStream("c:\\data\\output-text.txt"); 02   03

Java IO: FileInputStream

原文链接 作者: Jakob Jenkov 译者: 李璟([email protected]) FileInputStream可以以字节流的形式读取文件内容.FileInputStream是InputStream的子类,这意味着你可以把FileInputStream当做InputStream使用(FileInputStream与InputStream的行为类似). 这是一个FileInputStream的例子: 01 InputStream input = new FileInputStream

Java IO 学习总结 学习手册总结

Java IO 是一套Java用来读写数据(输入和输出)的API.大部分程序都要处理一些输入,并由输入产生一些输出.Java为此提供了java.io包. 代码 github地址:https://github.com/loveincode/StudyTest/tree/master/src/IO Java.io 包的范围 java.io 包并没有涵盖所有输入输出类型.例如,并不包含GUI或者网页上的输入输出,这些输入和输出在其它地方都涉及,比如Swing工程中的JFC (Java Foundati

Java IO教程

1  Java IO 教程 2 Java IO 概述 3 Java IO: 文件 4 Java IO: 管道 5 Java IO: 网络 6 Java IO: 字节和字符数组 7 Java IO: System.in, System.out, and System.error 8 Java IO: 流 9 Java IO: Input Parsing(暂无翻译,处理中) 10 Java IO: Readers and Writers 11 Java IO: 并发IO 12 Java IO: 异常