1. 程式人生 > >java IO包裝流如何關閉

java IO包裝流如何關閉

http 處理 write buffer itl 方法 test 技術 pos

問題:

(1)JAVA的IO流使用了裝飾模式,關閉最外面的流的時候會自動調用被包裝的流的close()方嗎?

(2)如果按順序關閉流,是從內層流到外層流關閉還是從外層到內存關閉?

問題(1)解釋:

技術分享圖片
如下例子代碼:
  FileInputStream is = new FileInputStream(".");   
  BufferedInputStream bis = new BufferedInputStream(is);  
  bis.close();

 
從設計模式上看:
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 關閉此輸入流並釋放與該流關聯的所有系統資源。
技術分享圖片

因此,可以只調用外層流的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();
      
     }

驗證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(); }
報出異常:

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異常;

轉自http://www.cnblogs.com/qqzy168/p/3670915.html

java IO包裝流如何關閉