开发者

Closing nested Reader

开发者 https://www.devze.com 2023-02-08 13:53 出处:网络
When reading from a text file, one typically creates a FileReader and then nests that in a BufferedReader. Which of the two readers should I close when I\'m done reading? Does it matter?

When reading from a text file, one typically creates a FileReader and then nests that in a BufferedReader. Which of the two readers should I close when I'm done reading? Does it matter?

FileReader fr = null;
BufferedReader br = null;
try
{
    fr = new FileReader(fi开发者_如何转开发leName);
    br = new BufferedReader(fr);
    // ...
}
finally
{
    // should I close fr or br here?
}

I'm a little paranoid when it comes to exception-safety. What happens when the BufferedReader constructor throws an exception? Does it close the nested reader? Or is it guaranteed not to throw?


Generally, close() on the outermost stream wrapper will call close() on the wrapped streams. However, if you think it's likely that a constructor will throw an exception, make liberal use of the Closeable interface.

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

So, even if the JVM ran out of heap space for the buffer and threw an error, you wouldn't leak a file handle.

For Java 7 and above use try-with-resources:

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


Closing only the BufferedReader is enough, cause it wraps the FileReader. If you look at the source code of BufferedReader you will see that the close method, closes the wrapped stream.


Close the BufferedReader in a finally block.


If you call the BufferedReader's close method, the BufferedReader will call the FileReader's close method. Thus both close method's are called. More precisely the BufferedReader will do nothing BUT calling the FileReader's close method. Thus it does not matter at all. Though I think it is good practice too call the BufferedReader's close method.


Nothing is guaranteed not to throw. Because the buffer is allocated it may throw OutOfMemoryError. I usually separate my code into 2 sections: acquire resources and then use resources. Each section usually has unique cleanup needs

Here is the code to illustrate:

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

And I agree with you, there is nothing worth than silently loose a file handler in the long running server application.

0

精彩评论

暂无评论...
验证码 换一张
取 消