Java 我必须关闭由PrintStream包装的FileOutputStream吗?

Java 我必须关闭由PrintStream包装的FileOutputStream吗?,java,stream,Java,Stream,我将FileOutputStream与PrintStream一起使用,如下所示: class PrintStreamDemo { public static void main(String args[]) { FileOutputStream out; PrintStream ps; // declare a print stream object try { // Create a new file ou

我将
FileOutputStream
PrintStream
一起使用,如下所示:

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");
        }
    }
}

我只关闭
打印流
。我是否还需要关闭
FileOutputStream
out.close();
)?

否,根据javadoc,关闭方法将为您关闭底层流。

否,您只需要关闭最外层的流。它将一路委托给包装的流

但是,您的代码包含一个概念性故障,关闭应该发生在
finally
中,否则当代码在打开和关闭之间抛出异常时,它永远不会关闭

例如

(请注意,我将代码更改为抛出异常,以便您了解问题的原因,即异常包含有关问题原因的详细信息)

或者,当您已经使用Java 7时,还可以使用ARM(自动资源管理;也称为),这样您就不需要自己关闭任何东西:

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;
    }
}

不,你不需要。PrintStream.close方法自动关闭下划线输出流

检查API


否,下面是
PrintStream
close()
方法的实现:

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()

否。不需要关闭其他组件。关闭流时,它会自动关闭其他相关组件。

查看源代码:顺便说一句,PrintStream的优点在于,您可以将它与字符串(用于文件名)或文件对象一起使用。您不需要打开FOStream就可以在PrintStream中使用它。当我添加finally block并尝试执行
ps.close()
时,我得到一个错误:
变量ps可能尚未初始化
您需要使用
null
对其进行初始化。请注意,我用一个更简洁的Java 7示例更新了答案。
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;
        }
    }