【问题标题】:Do I have to close FileOutputStream which is wrapped by PrintStream?我是否必须关闭由 PrintStream 包装的 FileOutputStream?
【发布时间】:2011-12-26 05:01:58
【问题描述】:

我正在使用 FileOutputStreamPrintStream,如下所示:

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();) 吗?

【问题讨论】:

  • 顺便说一句,PrintStream 的美妙之处在于您可以将它与一个字符串(用于文件名)或一个文件对象一起使用。您无需打开 FOStream 即可在 PrintStream 中使用它。

标签: java stream


【解决方案1】:

不,你只需要关闭最外面的流。它将一直委托给包装的流。

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

例如

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

【讨论】:

  • 当我添加 finally 块并尝试在其中执行 ps.close() 时出现错误:variable ps might not have been initialized
  • 你需要用null初始化它。
  • 请注意,我用更简洁的 Java 7 示例更新了答案。
【解决方案2】:

不,这里是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();关闭了输出流。

【讨论】:

    【解决方案3】:

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

    检查 API。

    http://download.oracle.com/javase/6/docs/api/java/io/PrintStream.html#close%28%29

    【讨论】:

      【解决方案4】:

      不,根据 javadoc,close 方法将为您提供close 底层流。

      【讨论】:

        【解决方案5】:

        没有。不需要关闭其他组件。当您关闭流时,它会自动关闭其他相关组件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-04-05
          • 1970-01-01
          • 2020-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-24
          相关资源
          最近更新 更多