> 所有的流,無論是輸入流還是輸出流,使用完畢之后,都應該關閉。 如果不關閉,會產生對資源占用的浪費。 當量比較大的時候,會影響到業務的正常開展。
# 在try中關閉
在try的作用域里關閉文件輸入流,在前面的示例中都是使用這種方式,這樣做有一個弊端;
如果文件不存在,或者讀取的時候出現問題而拋出異常,那么就不會執行這一行關閉流的代碼,存在巨大的資源占用隱患。 **不推薦使用**
```
package com.dodoke.util;
import java.io.File;
import java.io.FileInputStream;
public class TestSteam3 {
public static void main(String[] args) {
try {
// 準備文件lol.txt其中的內容是AB,對應的ASCII分別是65 66
File f = new File("d:/log.txt");
// 創建基于文件的輸入流
FileInputStream fis = new FileInputStream(f);
// 創建字節數組,其長度就是文件的長度
byte[] all = new byte[(int) f.length()];
// 以字節流的形式讀取文件的所有內容
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
// 每次使用完流,都應該進行關閉
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
# 在finally中關閉
這是標準的關閉流的方式
1. 首先把流的引用聲明在try的外面,如果聲明在try里面,其作用域無法抵達finally.
2. 在finally關閉之前,要先判斷該引用是否為空
3. 關閉的時候,需要再一次進行`try catch`處理
這是標準的嚴謹的關閉流的方式,但是看上去很繁瑣,所以寫不重要的或者測試代碼的時候,都會采用上面的有**隱患try**的方式,因為不麻煩~
```
package com.dodoke.util;
import java.io.File;
import java.io.FileInputStream;
public class TestSteam3 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
// 準備文件lol.txt其中的內容是AB,對應的ASCII分別是65 66
File f = new File("d:/log.txt");
// 創建基于文件的輸入流
fis = new FileInputStream(f);
// 創建字節數組,其長度就是文件的長度
byte[] all = new byte[(int) f.length()];
// 以字節流的形式讀取文件的所有內容
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 在finally 里關閉流
if (null != fis) {
try {
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
```
# 使用try()的方式
把流定義在`try()`里,try,catch或者finally結束的時候,會自動關閉
這種編寫代碼的方式叫做 **`try-with-resources`**, 這是從JDK7開始支持的技術
所有的流,都實現了一個接口叫做 **`AutoCloseable`**,任何類實現了這個接口,都可以在`try()`中進行實例化。 并且在try, catch, finally結束的時候自動關閉,回收相關資源。
```
package com.dodoke.util;
import java.io.File;
import java.io.FileInputStream;
public class TestSteam3 {
public static void main(String[] args) {
// 準備文件lol.txt其中的內容是AB,對應的ASCII分別是65 66
File f = new File("d:/log.txt");
try (FileInputStream fis = new FileInputStream(f);) {
// 創建字節數組,其長度就是文件的長度
byte[] all = new byte[(int) f.length()];
// 以字節流的形式讀取文件的所有內容
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
```