2011-11-10 36 views
14

我使用FileOutputStream中與PrintStream的是這樣的:我是否必須關閉由PrintStream包裝的FileOutputStream?

class PrintStreamDemo { 
    public static void main(String args[]){ 
    FileOutputStream out; 
    PrintStream ps; // declare a print stream object 
    try { 
    // Create a new file output stream 
    out = new FileOutputStream("myfile.txt"); 

    // Connect print stream to the output stream 
    ps = new PrintStream(out); 

    ps.println ("This data is written to a file:"); 
    System.err.println ("Write successfully"); 
    ps.close(); 
    } 
    catch (Exception e){ 
    System.err.println ("Error in writing to file"); 
    } 
    } 
} 

林僅關閉的PrintStream。 我是否需要關閉FileOutputStream(out.close();)?

+0

查看源代碼:http://www.docjar.com/html/api/java/io/PrintStream.java.html – jtoberon

+0

順便說一下,PrintStream的美妙之處在於,您可以使用它一個String(用於文件名)或一個File對象。您不需要打開一個FOStream只是在PrintStream中使用它。 – Mechkov

回答

22

不,您只需關閉最外面的流。它將一直委託給包裝流。

但是,您的代碼包含一個概念性故障,關閉應該發生在finally,否則當代碼在打開和關閉之間引發異常時,它從不關閉。

E.g.

public static void main(String args[]) throws IOException { 
    PrintStream ps = null; 

    try { 
     ps = new PrintStream(new FileOutputStream("myfile.txt")); 
     ps.println("This data is written to a file:"); 
     System.out.println("Write successfully"); 
    } catch (IOException e) { 
     System.err.println("Error in writing to file"); 
     throw e; 
    } finally { 
     if (ps != null) ps.close(); 
    } 
} 

(請注意,我改變了代碼拋出例外,讓你瞭解這個問題的原因,異常即包含有關該問題的原因的詳細信息)

或者,如果您已經使用Java 7,則還可以使用ARM(自動資源管理;也稱爲try-with-resources),以便您不需要自己關閉任何東西:

public static void main(String args[]) throws IOException { 
    try (PrintStream ps = new PrintStream(new FileOutputStream("myfile.txt"))) { 
     ps.println("This data is written to a file:"); 
     System.out.println("Write successfully"); 
    } catch (IOException e) { 
     System.err.println("Error in writing to file"); 
     throw e; 
    } 
} 
+0

當我添加finally塊,並嘗試做'ps.close()'在那裏我得到錯誤:'變量ps可能沒有被初始化' – hs2d

+0

你需要用'null'初始化它。 – BalusC

+0

啊,沒想到,謝謝! – hs2d

3

不,根據javadoc,close方法將close作爲您的底層流。

5

不,這裏是實現PrintStreamclose()方法:

public void close() { 
    synchronized (this) { 
     if (! closing) { 
     closing = true; 
     try { 
      textOut.close(); 
      out.close(); 
     } 
     catch (IOException x) { 
      trouble = true; 
     } 
     textOut = null; 
     charOut = null; 
     out = null; 
     } 
    } 

你可以看到out.close();其關閉輸出流。

相關問題