當前位置:
首頁 > 知識 > 使用try-with-resources優雅的關閉IO流

使用try-with-resources優雅的關閉IO流

Java類庫中包括許多必須通過調用close方法來手工關閉的資源。例如InputStream、OutputStream和java.sql.Connection。客戶端經常會忽略資源的關閉,造成嚴重的性能後果也就可想而知了。根據經驗,try-finally 語句是確保資源會被適當關閉的最佳方法,就算是發生異常或者返回也一樣:

Copypublic String tryfinally(String path) throws IOException {

BufferedReader reader = new BufferedReader(new FileReader(new File(path))); try{ return reader.readLine();

}finally {

reader.close();

}

}

即便用 try-finally 語句正確地關閉了資源,它也存在著些許不足。因為在try塊和finally塊中的代碼,都會拋出異常。例如,底層的物理設備出現異常,那麼調用readLine就會拋出異常,基於同樣的原因,調用close也會出現異常。在這種情況下,第二個異常完全抹除了第一個異常。在異常堆棧軌跡中,完全沒有關於第一個異常的記錄,這在現實的系統中會導致調試變得非常複雜,因為通常需要看到第一個異常的記錄,這在現實的系統中會導致調試變得非常複雜,因為通常需要看到第一個異常才能診斷出問題何在。雖然可以通過編寫代碼來禁止第二個異常,保留第一個異常,但事實上沒有人會這麼做,因為實現起來太繁瑣了。

如何完美解決這種問題呢?當然是Java7中引入的 try-with-resources 語句。

還是上面的這段代碼,使用 try-with-resources 語句之後,新的代碼如下:

Copypublic String tryresources(String path) throws IOException { try(BufferedReader reader = new BufferedReader(new FileReader(new File(path)))){ return reader.readLine();

}

}

使用這種 try-with-resources 不僅使代碼變得簡潔易懂,也更容易進行診斷。以上段代碼為例,如果調用 readLine 和 不可見的 close 方法都拋出異常,後一個異常就會被禁止,以保留第一個異常。事實上,為了保留你想看到的那個異常,即便多個異常都可以被禁止。這些被禁止的異常並不是簡單地被拋棄了,而是會被列印在堆棧軌跡中,並註明它們是被禁止的異常。通過編程調用 getSuppressed 方法還可以訪問到它們,getSuppressed 方法也已經添加在Java7的Throwable中了。

使用 try-with-resources 語句有什麼要求嗎?

是的,要使用這個構造的資源,必須先實現 AutoCloseable 介面,其中包含了單個返回 void 的 close 方法。Java類庫與第三方類庫中的許多類和介面,現在都實現或擴展了 AutoCloseable 介面。

Copypublic interface AutoCloseable { void close() throws Exception;

}

以下是使用 try-with-resources 的第二個範例:

Copyvoid tryresources(String src,String dst) throws IOException { try(InputStream in = new FileInputStream(src);

OutputStream out = new FileOutputStream(dst)){ byte[] bytes = new byte[1024]; int n; while ((n=in.read(bytes))=0){

out.write(bytes,0,n);

}

}

}

在 try-with-resources 語句中還可以使用 catch 子句,就像在平時的 try-finally 語句中一樣。

Copypublic String tryresources(String path){ try(BufferedReader reader = new BufferedReader(new FileReader(new File(path)))){ return reader.readLine();

} catch (IOException e) { return null;

}

}

有了 try-with-resources 語句,在使用必須關閉的資源時,就能更輕鬆地正確編寫代碼了。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 千鋒JAVA開發學院 的精彩文章:

分享:更好的SQL查詢如何做到
分散式系列:Vector clock

TAG:千鋒JAVA開發學院 |