我們在JAVA項目中會處理流,流使用完成后一定要注意關閉流,但是在關閉流時有一些注意點容易忽略,我們以文件流為例先看兩個錯誤實例。
/** * 錯誤實例1 * * @author 今日頭條號「IT徐胖子」 * */public class Test1 {public void copyFile() {FileReader fr = null;FileWriter fw = null;try {fr = new FileReader("c:\aaa.txt"); // 代碼1fw = new FileWriter("c:\bbb.txt"); // 代碼2char[] charBuffer = new char[1024];int len = 0;while ((len = fr.read(charBuffer)) != -1) {fw.write(charBuffer, 0, len);}System.out.println("文件復制成功");} catch (IOException e) {throw new RuntimeException("文件復制失敗");} finally {try {fr.close(); // 代碼3fw.close(); // 代碼4} catch (IOException e) {throw new RuntimeException("流關閉失敗");}}}}
Test1問題在于如果代碼1出錯,fr根本就沒有初始化,執行代碼3時就會報空指針異常。代碼2和代碼4同樣是這個道理。
/** * 錯誤實例2 * * @author 今日頭條號「IT徐胖子」 * */public class Test2 {public void copyFile() {FileReader fr = null;FileWriter fw = null;try {fr = new FileReader("c:\aaa.txt"); // 代碼1fw = new FileWriter("c:\bbb.txt"); // 代碼2char[] charBuffer = new char[1024];int len = 0;while ((len = fr.read(charBuffer)) != -1) {fw.write(charBuffer, 0, len);}System.out.println("文件復制成功");} catch (IOException e) {throw new RuntimeException("文件復制失敗");} finally {try {if (null != fr) {fr.close(); // 代碼3}if (null != fw) {fw.close(); // 代碼4}} catch (IOException e) {throw new RuntimeException("流關閉失敗"); // 代碼5}}}}
Test2加上是否為空的判斷可以避免空指針異常。但是如果代碼3執行出錯,程序會直接進入代碼5,而代碼4根本沒有得到執行,導致流無法關閉。我們來看一個正確實例。
/** * 正確實例 * * @author 今日頭條號「IT徐胖子」 * */public class Test3 {public void copyFile() {FileReader fr = null;FileWriter fw = null;try {fr = new FileReader("c:\aaa.txt");fw = new FileWriter("c:\bbb.txt");char[] charBuffer = new char[1024];int len = 0;while ((len = fr.read(charBuffer)) != -1) {fw.write(charBuffer, 0, len);}System.out.println("文件復制成功");} catch (IOException e) {throw new RuntimeException("文件復制失敗");} finally {try {if (null != fr) {fr.close();}} catch (IOException e) {throw new RuntimeException("流關閉失敗");}try {if (null != fw) {fw.close();}} catch (IOException e) {throw new RuntimeException("流關閉失敗");}}}}