There are a few examples where people call close()
in their finally
block when writing to a file, like this:
OutputStream out = null;
try {
out = new FileOutputStream(file);
out.write(data);
out.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
But there are many more examples, including the official Android docs where they don't do that:
try {
OutputStream out = new FileOutputStream(file);
out.write(data);
out.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
Given that the second example is much shorter, is it really necessary to call close()
in finally
as shown above or is there some mechanism that would clean up the file handle automatically?
Every situation is a little bit different, but it's best to always close in a finally block OR use java's try with resources syntax, which is effectively the same thing.
The risk you run by not closing in the finally block is that you end up with an unclosed stream object after the catch gets triggered. Also, if your stream is buffered, you might need that final close to flush the buffer to ensure that the write is fully complete. It may be a critical error to complete without that final close.
Not closing the file may mean the stream contents don't get flushed in a timely way. This is a concern in the case that the code completes normally and doesn't throw an exception.
If you don't close a FileOutputStream, then its finalize method will try to close it. However, finalize doesn't get called immediately, it is not guaranteed to get called at all, see this question. It would be better not to rely on this.
If JDK7's try-with-resources is an option then use it:
try (OutputStream out = new FileOutputStream(file);) {
out.write(data);
}
Otherwise, for JDK6, make sure the exception thrown on close can't mask any exception thrown in the try block:
OutputStream out = new FileOutputStream(file);
try {
out.write(data);
} finally {
try {
out.close();
} catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
It may be verbose but it makes sure the file gets closed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With