系统学习 Java IO (二)----IO 异常处理

目录:系统学习 Java IO---- 目录,概览html

咱们使用流后,须要正确关闭 Streams 和 Readers / Writers 。
这是经过调用 close() 方法完成的,看看下面这段代码:
```java
InputStream input = new FileInputStream("D:\out.txt");java

int data = input.read();
while(data != -1) {
//do something with data...
doSomethingWithData(data);
data = input.read();
}
input.close();
```ide

这段代码乍一看彷佛没问题。
可是若是从 doSomethingWithData() 方法内部抛出异常会发生什么?
对!input.close(); 将得不到执行的机会,InputStream 永远不会关闭!
为避免这种状况,能够把关闭流的代码放在 finally 块里面确保必定被执行,将代码重写为:学习

InputStream input = null;

try{
  input = new FileInputStream("D:\\out.txt");

  int data = input.read();
  while(data != -1) {
      //do something with data...
      doSomethingWithData(data);
      data = input.read();
  }
}catch(IOException e){
  //do something with e... log
} finally {
  if(input != null) input.close();
}

可是若是 close() 方法自己抛出异常会发生什么? 这样流会被关闭吗?
好吧,要捕获这种状况,你必须在 try-catch 块中包含对 close() 的调用,以下所示:线程

} finally {
     try{
       if(input != null) input.close();
     } catch(IOException e){
       //do something, or ignore.
     }
   }

这样确实能够解决问题,就是太啰嗦太难看了。
有一种方法能够解决这个问题。就是把这些重复代码抽出来定义一个方法,这些解决方案称为“异常处理模板”。
建立一个异常处理模板,在使用后正确关闭流。此模板只编写一次,并在整个代码中重复使用,但感受仍是挺麻烦的,就不展开讲了。code

还好,从 Java 7 开始,咱们可使用名为 try-with-resources 的构造,htm

// 直接在 try 的小括号里面打开流
try(FileInputStream input = new FileInputStream("file.txt")) {
        int data = input.read();
        while(data != -1){
            System.out.print((char) data);
            data = input.read();
        }   }

当try块完成时,FileInputStream 将自动关闭,换句话说,只要线程已经执行出try代码块,inputstream 就会被关闭。
由于 FileInputStream 实现了 Java 接口 java.lang.AutoCloseable ,
实现此接口的全部类均可以在 try-with-resources 构造中使用。blog

public interface AutoCloseable {
   void close() throws Exception;
}

FileInputStream 重写了这个 close() 方法,查看源码能够看到其底层是调用 native 方法进行操做的。接口

try-with-resources构造不只适用于Java的内置类。
还能够在本身的类中实现 java.lang.AutoCloseable 接口,
并将它们与 try-with-resources 构造一块儿使用,如:资源

public class MyAutoClosable implements AutoCloseable {
    public void doIt() {
        System.out.println("MyAutoClosable doing it!");
    }
    @Override
    public void close() throws Exception {
        System.out.println("MyAutoClosable closed!");
    }  }
private static void myAutoClosable() throws Exception {
    try(MyAutoClosable myAutoClosable = new MyAutoClosable()){
        myAutoClosable.doIt();
    }
}
// 将会输出:
// MyAutoClosable doing it!
// MyAutoClosable closed!

try-with-resources 是一种很是强大的方法,能够确保 try-catch 块中使用的资源正确关闭, 不管这些资源是您本身的建立,仍是 Java 的内置组件。

相关文章
相关标签/搜索