目錄:系統學習 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 的內置組件。