关闭嵌套读取器

从文本文件中读取时,通常会创建一个,然后将其嵌套在 .当我读完后,我应该关闭两个读者中的哪一个?这重要吗?FileReaderBufferedReader

FileReader fr = null;
BufferedReader br = null;
try
{
    fr = new FileReader(fileName);
    br = new BufferedReader(fr);
    // ...
}
finally
{
    // should I close fr or br here?
}

在异常安全方面,我有点偏执。当构造函数引发异常时会发生什么情况?它是否关闭嵌套读取器?还是保证不会投掷?BufferedReader


答案 1

通常,在最外层的流包装器将调用包装的流。但是,如果您认为构造函数可能会引发异常,请大量使用 Closeable 接口。close()close()

FileReader fr = new FileReader(fileName);
Closeable res = fr;
try {
    BufferedReader br = new BufferedReader(fr);
    res = br;
} finally {
    res.close();
}

因此,即使 JVM 耗尽了缓冲区的堆空间并抛出了错误,您也不会泄漏文件句柄。

对于 Java 7 及更高版本,请使用 try-with-resources:

try (FileReader fr = new FileReader(fileName);
    BufferedReader br = new BufferedReader(fr)) {
  // do work
}

答案 2

仅关闭 就足够了,因为它会包装 .如果你看一下源代码,你会看到该方法,关闭了包装的流。BufferedReaderFileReaderBufferedReaderclose