問題:
(1)JAVA的IO流使用了裝飾模式,關閉最外面的流的時候會自動調用被包裝的流的close()方嗎?
(2)若是按順序關閉流,是從內層流到外層流關閉仍是從外層到內存關閉?java
問題(1)解釋: 設計模式
以下例子代碼:
FileInputStream is = new FileInputStream(".");
BufferedInputStream bis = new BufferedInputStream(is);
bis.close();api
從設計模式上看:
java.io.BufferedInputStream是java.io.InputStream的裝飾類。
BufferedInputStream裝飾一個 InputStream 使之具備緩衝功能,is要關閉只須要調用最終被裝飾出的對象的 close()方法便可,由於它最終會調用真正數據源對象的 close()方法。
BufferedInputStream的close方法中對InputStream進行了關閉,下面是jdk中附帶的源代碼:
java.io.BufferedInputStream的api:
close
public void close()throws IOException 關閉此輸入流並釋放與該流關聯的全部系統資源。spa
所以,能夠只調用外層流的close方法關閉其裝飾的內層流,驗證例子:設計
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("d:\\a.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
bw.write("java IO close test");
bw.close();
}code
驗證ok對象
問題(2)解釋:若是不想使用(1)方式關閉流,能夠逐個關閉流(可能你們比較習慣吧)內存
以下例子:
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("d:\\a.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
bw.write("java IO close test");
//從內帶外順序順序會報異常
fos.close();
osw.close();
bw.close();資源
}
報出異常:it
Exception in thread "main" java.io.IOException: Stream closed
at sun.nio.cs.StreamEncoder.ensureOpen(StreamEncoder.java:26)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:99)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111)
at java.io.BufferedWriter.close(BufferedWriter.java:246)
at com.my.test.QQ.main(QQ.java:22)
以下例子:
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("d:\\a.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
bw.write("java IO close test");
// 從外到內順序關閉ok
bw.close();
osw.close();
fos.close();
}
驗證ok
總結:
通常狀況下是:先打開的後關閉,後打開的先關閉
另外一種狀況:看依賴關係,若是流a依賴流b,應該先關閉流a,再關閉流b 例如處理流a依賴節點流b,應該先關閉處理流a,再關閉節點流b 固然徹底能夠只關閉處理流,不用關閉節點流。處理流關閉的時候,會調用其處理的節點流的關閉方法 若是將節點流關閉之後再關閉處理流,會拋出IO異常;