从文本文件中读取时,通常会创建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
构造函数抛出异常时会发生什么?它是否关闭了嵌套的阅读器?还是保证不扔?
答案 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( );
}
我同意你的观点,没有什么比在长时间运行的服务器应用程序中无声地松散文件处理程序更值得。