当我的程序启动时,它会打开一个文件并定期写入它。 (它不是一个日志文件;它是该程序的输出之一。)我需要在程序的长度内提供该文件,但我不需要做任何事情特别是结束文件;关闭它。
我收集了Java中的文件I / O,我应该实现AutoCloseable
并将其包装在try-with-resources块中。但是,因为这个文件是长寿的,并且它是程序的一些输出之一,所以我发现很难组织一些事情,以便我打开的所有文件都包含在try-with-资源块。此外,顶级课程(我的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; dr 我是否需要实现AutoCloseable
并调用writer.close()
如果资源是打开的输出文件,我永远不需要关闭它直到程序是做了什么?我可以假设JVM和操作系统(Linux)会自动为我清理吗?
奖金(?):我也在C#' s IDisposeable
中努力解决这个问题。 {I} {s}}块就像Java的try-with-resources构造一样,当我有一些我要打开的东西,快速做某事并立即关闭时,这是一个很好的功能。但通常情况并非如此,特别是对于文件,当对该资源的访问暂停一段时间,或者需要管理多个这样的资源时。如果我的问题的答案是"总是使用try-with-resources块"我再次陷入困境。
答案 0 :(得分:0)
我有类似的代码,它不适合用try-with-resources语句包装。我认为这很好,只要你在程序完成后关闭它。
请确保您考虑可能发生的任何Exceptions
。例如,在我的程序中,有一个cleanup()
方法在程序关闭时被调用。这会调用writer.close()
。如果存在任何导致程序关闭的异常行为,也会调用此方法。
如果这只是一个简单的程序,并且您期望Writer
在其持续时间内开放,我不会认为这对它来说真的很重要。程序终止时不要关闭......但 是确保资源关闭的良好做法,因此我会继续将其添加到您的程序可能关闭的任何位置。
答案 1 :(得分:0)
您应该始终关闭资源或将它们设置为null,以便Java中的垃圾收集器可以捕获它们。使用try-with-resource块是让Java在完成资源后自动关闭资源的好方法。即使你在程序的持续时间内使用它,即使在最后也是很好的编程习惯。有些人可能会说你不需要,我个人会说继续这样做,这就是原因:
“当不再需要流时,始终使用close()方法关闭它,或者使用try-with-resource语句自动关闭它。不关闭流可能会导致输出文件中的数据损坏,或者其他编程错误。“
- Java编程第10版简介,Y。Daniel Liang
如果可能,只需在程序最后的资源上运行.close()方法。
答案 2 :(得分:0)
我(现在)认为更好的答案是“它取决于”:-)。 Lukas Eder提供了详细的治疗here。另请查看Lambda EG group post。
但总的来说,最好在完成后将资源返回给操作系统并始终使用try-with-resources
(除非你知道自己在做什么)。