Java IO包裝流如何關閉?

問題:
(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異常;

相關文章
相關標籤/搜索