java.io.exception_Java IO: 异常处理

原文链接 作者:Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com)

流与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获得更多信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值