您好,登錄后才能下訂單哦!
在Java編程過程中,如果打開了外部資源(文件、數據庫連接、網絡連接等),我們必須在這些外部資源使用完畢后,手動關閉它們。
因為外部資源不由JVM管理,無法享用JVM的垃圾回收機制,如果我們不在編程時確保在正確的時機關閉外部資源,就會導致外部資源泄露,緊接著就會出現文件被異常占用,數據庫連接過多導致連接池溢出等諸多很嚴重的問題。
為了確保外部資源一定要被關閉,通常關閉代碼被寫入finally代碼塊中,當然我們還必須注意到關閉資源時可能拋出的異常,于是變有了下面的經典代碼
public static void main(String[] args) { FileInputStream inputStream = null; try { inputStream = new FileInputStream(new File("test")); System.out.println(inputStream.read()); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } } } }
換成try-with-resource
public static void main(String[] args) { try (FileInputStream inputStream = new FileInputStream(new File("test"))) { System.out.println(inputStream.read()); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } }
再以一個java里面讀取文件和寫入文件為例子
/** * @ Author zhangsf * @CreateTime 2019/11/27 - 13:05 */ package Advanced; import java.io.File; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileWriter; public class ReadTxt1 { public static void main(String args[]) { try { // 防止文件建立或讀取失敗,用catch捕捉錯誤并打印,也可以throw /* 讀入TXT文件 */ String pathname = "E:\\python_file\\web_spider\\input.txt"; // 絕對路徑或相對路徑都可以,這里是絕對路徑,寫入文件時演示相對路徑 File filename = new File(pathname); // 要讀取以上路徑的input。txt文件 InputStreamReader reader = new InputStreamReader( new FileInputStream(filename)); // 建立一個輸入流對象reader BufferedReader br = new BufferedReader(reader); // 建立一個對象,它把文件內容轉成計算機能讀懂的語言 String line = ""; line = br.readLine(); while (line != null) { line = br.readLine(); // 一次讀入一行數據 System.out.println(line); } /* 寫入Txt文件 */ File writename = new File("E:\\python_file\\web_spider\\output.txt"); // 相對路徑,如果沒有則要建立一個新的output。txt文件 writename.createNewFile(); // 創建新文件 BufferedWriter out = new BufferedWriter(new FileWriter(writename)); out.write("開始寫入文件啦\r\n"); // \r\n即為換行 out.flush(); // 把緩存區內容壓入文件 out.close(); // 最后記得關閉文件 } catch (Exception e) { e.printStackTrace(); } } }
當一個外部資源的句柄對象實現了AutoCloseable接口,JDK7中便可以利用try-with-resource語法更優雅的關閉資源,消除板式代碼。
在JDK7以前,Java沒有自動關閉外部資源的語法特性,直到JDK7中新增了try-with-resource語法,那么將上面java的讀文件和寫文件重新按照try-with-resource語法實現
/** * @ Author zhangsf * @CreateTime 2019/11/27 - 11:44 */ package Advanced; import java.io.*; public class ReadTxt { public static void main(String args[]) { readFile(); writeFile(); } /** * 讀入TXT文件 */ public static void readFile() { String pathname = "E:\\python_file\\web_spider\\input.txt"; // 絕對路徑或相對路徑都可以,寫入文件時演示相對路徑, // 讀取以上路徑的input.txt文件 //防止文件建立或讀取失敗,用catch捕捉錯誤并打印,也可以throw; //不關閉文件會導致資源的泄露,讀寫文件都同理 //Java7的try-with-resources可以優雅關閉文件,異常時自動關閉文件;詳細解讀https://stackoverflow.com/a/12665271 try (FileReader reader = new FileReader(pathname); BufferedReader br = new BufferedReader(reader) // 建立一個對象,它把文件內容轉成計算機能讀懂的語言 ) { String line; //推薦更加簡潔的寫法 while ((line = br.readLine()) != null) { // 一次讀入一行數據 System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } /** * 寫入TXT文件 */ public static void writeFile() { try { File writeName = new File("E:\\python_file\\web_spider\\output2.txt"); // 相對路徑,如果沒有則要建立一個新的output.txt文件 writeName.createNewFile(); // 創建新文件,有同名的文件的話直接覆蓋 try (FileWriter writer = new FileWriter(writeName); BufferedWriter out = new BufferedWriter(writer) ) { out.write("我開始寫入文件啦1\r\n"); // \r\n即為換行 out.write("我開始寫入文件啦2\r\n"); // \r\n即為換行 out.flush(); // 把緩存區內容壓入文件 } } catch (IOException e) { e.printStackTrace(); } } }
將外部資源的句柄對象的創建放在try關鍵字后面的括號中,當這個try-catch代碼塊執行完畢后,Java會確保外部資源的close方法被調用。簡潔很多。
try-with-resource語法涉及的另外一個知識點,叫做異常抑制。當對外部資源進行處理(例如讀或寫)時,如果遭遇了異常,且在隨后的關閉外部資源過程中,又遭遇了異常,那么你catch到的將會是對外部資源進行處理時遭遇的異常,關閉資源時遭遇的異常將被“抑制”但不是丟棄,通過異常的getSuppressed方法,可以提取出被抑制的異常。
try-with-resource時,如果對外部資源的處理和對外部資源的關閉均遭遇了異常,“關閉異常”將被抑制,“處理異常”將被拋出,但“關閉異常”并沒有丟失,而是存放在“處理異常”的被抑制的異常列表
以上就是Java使用try-with-resource來優雅地關閉資源的詳細內容,更多請關注億速云其它相關文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。