我是否需要关闭()FileReader和BufferedReader?

Zil*_*ilk 179 java io filereader bufferedreader

我正在使用围绕FileReader的BufferedReader读取本地文件:

BufferedReader reader = new BufferedReader(new FileReader(fileName));
// read the file
// (error handling snipped)
reader.close();
Run Code Online (Sandbox Code Playgroud)

我需要close()FileReader为好,或将包装处理这个问题?我见过人们这样做的代码:

FileReader fReader = new FileReader(fileName);
BufferedReader bReader = new BufferedReader(fReader);
// read the file
// (error handling snipped)
bReader.close();
fReader.close();
Run Code Online (Sandbox Code Playgroud)

从servlet调用此方法,我想确保不打开任何句柄.

Atm*_*ons 199

没有.

BufferedReader.close()
Run Code Online (Sandbox Code Playgroud)

根据BufferedReaderInputStreamReader的 javadoc 关闭流

以及

FileReader.close()
Run Code Online (Sandbox Code Playgroud)

确实.

  • 除非`BufferedReader`的构造函数抛出异常.关闭底层流更简洁,尽管你需要注意其他资源和缓冲的装饰器. (12认同)
  • Javadoc没有说'BufferedReader.close()`是否关闭了底层读者.它的描述只是从`Reader.close()`复制而来.这可能是实际中的实际行为,但没有记录. (9认同)
  • 无论实际文档是应该更改还是不应该更改都没关系,`Reader#close()`的javadoc不会说它是否关闭它包装的Reader.它所说的与之相关的是"关闭流并释放与之关联的任何系统资源."这不足以说明它是否关闭了资源."释放资源"也可以删除对BufferedReader中资源的任何引用...这意味着资源没有关闭. (6认同)
  • 如果实际行为不同,那么它应该被记录下来.否则文档是无用的.程序员应该能够将文档视为完整和具体的. (3认同)

McD*_*ell 95

正如其他人指出的那样,您只需要关闭外包装.

BufferedReader reader = new BufferedReader(new FileReader(fileName));
Run Code Online (Sandbox Code Playgroud)

如果BufferedReader构造函数抛出异常(例如OutOfMemoryError),则可能会泄漏文件句柄.如果您的应用程序处于此状态,那么清理需要多么谨慎可能取决于您不会剥夺操作系统可能要分配给其他程序的资源的重要性.

所述可关闭的,如果一个封装构造是可能在Java 5或6失败界面可用于:

Reader reader = new FileReader(fileName);
Closeable resource = reader;
try {
  BufferedReader buffered = new BufferedReader(reader);
  resource = buffered;
  // TODO: input
} finally {
  resource.close();
}
Run Code Online (Sandbox Code Playgroud)

Java 7代码应该使用try-with-resources模式:

try (Reader reader = new FileReader(fileName);
    BufferedReader buffered = new BufferedReader(reader)) {
  // TODO: input
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这非常有启发性. (4认同)
  • “Java 7 代码应该使用 try-with-resources 模式”。谢谢,这正是我一直在寻找的。该解决方案是在 09 年编写的,因此 try-with-resources 范例可能应该是新的建议。此外,它为 OP 提供了比已接受且得票较高的答案更好的答案。 (3认同)

Csa*_*a_H 5

根据BufferedReader源代码,在这种情况下bReader.close调用fReader.close,所以从技术上讲你不必调用后者.


Bri*_*new 5

BufferedReader的源代码显示,当您关闭BufferedReader时,底层已关闭。

  • 我真的很想为链接到一些具体的东西竖起大拇指,但这仅指 OpenJDK 实现,并且由于 JavaDocs 对 `Reader#close()` 不清楚,所以这不能提供具体的证据证明 Oracle JDK,例如,以类似的方式实现。 (2认同)

Anu*_*rma 5

检查源代码后,我发现对于示例:

FileReader fReader = new FileReader(fileName);
BufferedReader bReader = new BufferedReader(fReader);
Run Code Online (Sandbox Code Playgroud)

BufferedReader对象上的 close() 方法将调用Reader类的抽象 close() 方法,该方法最终将调用InputStreamReader类中的已实现方法,然后关闭InputStream对象。

所以,只有 bReader.close() 就足够了。

  • 源代码显示的内容不可作为参考引用。这是*规范*所说的,在这种情况下是Javadoc,可以依赖。 (5认同)