0

当我的程序启动时,它会打开一个文件并定期写入。(它不是日志文件;它是程序的输出之一。)我需要在程序的长度内使用该文件,但我不需要做任何特别的事情来结束文件;关闭它。

我为 Java 中的文件 I/O 收集了它,我应该实现AutoCloseable它并将其包装在一个 try-with-resources 块中。然而,因为这个文件是长期存在的,并且它是程序的少数输出之一,我发现很难组织我打开的所有文件都包含在 try-with-resources 块中的东西。此外,顶级类(我的main()函数所在的地方)不知道这个文件。

这是我的代码;注意缺乏writer.close()

public class WorkRecorder {

    public WorkRecorder(String recorderFile) throws FileNotFoundException {
        writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(recorderFile)));
    }

    private Writer writer;

    public void record(Data data) throws Exception {

        // format Data object to match expected file format
        // ...

        writer.write(event.toString());
        writer.write(System.lineSeparator());
        writer.flush();
    }
}

tl;博士如果资源是打开的输出文件,我是否需要实现AutoCloseable和调用writer.close(),并且在程序完成之前我不需要关闭它?我可以假设 JVM 和操作系统(Linux)会自动为我清理东西吗?

奖励(?):我在 C# 中IDisposeable也遇到了这个问题。这个using块,就像 Java 的 try-with-resources 构造一样,是一个很好的特性,当我有一些我要打开的东西,快速做一些事情,然后马上关闭。但通常情况并非如此,特别是对于文件,当对该资源的访问暂停一段时间,或者当需要管理多个此类资源时。如果我的问题的答案是“始终使用 try-with-resources 块”,我又被卡住了。

4

3 回答 3

0

我有类似的代码,不适合包含在 try-with-resources 语句中。我认为这很好,只要你在程序完成时关闭它。

只要确保你考虑到任何Exceptions可能发生的事情。例如,在我的程序中,有一个cleanup()方法在程序关闭时被调用。这调用writer.close(). 如果有任何异常行为会导致程序关闭,也会调用此方法。

如果这只是一个简单的程序,并且您希望Writer它在其持续时间内保持打开状态,那么我认为在程序终止时不关闭它并不是什么大不了的事......但这是一个好习惯确保您的资源已关闭,因此我会继续将其添加到您的程序可能关闭的任何地方。

于 2016-02-26T18:29:24.233 回答
0

您应该始终关闭资源或将它们设置为 null,以便它可以被 Java 中的垃圾收集器拾取。使用 try-with-resource 块是让 Java 在您使用完资源后自动关闭资源的好方法。即使您在程序期间使用它,即使在最后关闭它也是一种很好的编程习惯。有人可能会说你不需要,我个人会说继续做吧,原因如下:

“当不再需要某个流时,请始终使用 close() 方法关闭它或使用 try-with-resource 语句自动关闭它。不关闭流可能会导致输出文件中的数据损坏或其他编程错误。

-Java 编程简介第 10 版,Y. Daniel Liang

如果可能,只需在程序最后对资源运行 .close() 方法。

于 2016-02-26T18:33:48.767 回答
0

我(现在)认为更好的答案是“这取决于”:-)。Lukas Eder在这里提供了详细的处理方法。另请查看Lambda EG 组帖子

try-with-resources但一般来说,当您完成资源并一直使用它(除非您知道自己在做什么)时,将其返回给操作系统是一个好主意。

于 2016-02-26T20:55:07.340 回答