2011-02-05 75 views
12

从文本文件中读取数据时,通常会创建一个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构造函数抛出异常时会发生什么?它是否关闭嵌套的阅读器?还是保证不扔?

回答

9

通常,最外层流包装器上的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-与资源:

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

+1。比我的解决方案更优雅。 – 2011-02-05 21:03:08

0

仅合计BufferedReader就足够了,因为它包装了FileReader。如果您查看BufferedReadersource code,您将看到close方法将关闭包装的流。

+0

`buf = new char [8192];`Ew,幻数! – fredoverflow 2011-02-05 19:54:21

0

在finally块中关闭BufferedReader。

0

如果调用BufferedReader中的close方法,在BufferedReader类将调用的FileReader的close方法。因此这两个关闭方法都被调用。更确切地说,BufferedReader什么也不做但是调用FileReader的close方法。因此它根本不重要。虽然我认为这也是一个很好的做法,也可以调用BufferedReader的close方法。

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(); 
} 

而且我同意你的观点,没有什么价值超过默默地松在长时间运行的服务器应用程序的文件处理程序。