关闭嵌套的Reader

时间:2011-02-05 19:28:32

标签: java file-io stream resource-management try-finally

从文本文件中读取时,通常会创建FileReader,然后将其嵌套在BufferedReader中。我读完后应该关闭哪两个读者?这有关系吗?

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

在异常安全方面,我有点偏执。当BufferedReader构造函数抛出异常时会发生什么?它是否关闭了嵌套的阅读器?还是保证不扔?

5 个答案:

答案 0 :(得分:10)

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

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
}

答案 1 :(得分:0)

只关闭BufferedReader就足够了,因为它包裹了FileReader。如果您查看BufferedReader的{​​{3}},您会看到close方法,关闭已包装的流。

答案 2 :(得分:0)

关闭finally块中的BufferedReader。

答案 3 :(得分:0)

如果调用BufferedReader的close方法,BufferedReader将调用FileReader的close方法。因此,两个close方法都被调用。更确切地说,BufferedReader将不会执行任何操作 BUT 调用FileReader的close方法。因此,它根本不重要。虽然我认为这也是一个好习惯,但也要调用BufferedReader的密切方法。

答案 4 :(得分:0)

没有任何保证不扔。因为缓冲区已分配,所以可能会抛出OutOfMemoryError。我通常将我的代码分为两部分:获取资源然后使用资源。每个部分通常都有独特的清理需求

以下是代码说明:

// Acquire resources section.

final FileReader fr = new FileReader( fileName );

BufferedReader br = null;

try
{
    br = new BufferedReader(fr);
}
finally
{
    if ( br == null )
    {
        // Note that you are closing the fr here
        fr.close( );
    }
}

// Use resources section
try
{
    // ... use br
}
finally
{
    // Now that br is safely constructed, just all its close
    br.close( );
}

我同意你的观点,没有什么比在长时间运行的服务器应用程序中无声地松散文件处理程序更值得。