Is this code
BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"));
try {
bw.write("test");
} finally {
IOUtils.closeQuietly(bw);
}
safe or not? As far as I understand when we close a BufferedWriter it will flush its buffer to the underlying stream and may fail due to an error. But IOUtils.closeQuietly API says that any exceptions will be ignored.
Is it possible a data loss will go unnoticed due to IOUtils.closeQuietly?
Yes, it's safe to use it but only for Java6 and lower. From Java7, you should user try-with-resource.
It will eliminate much of the boilerplate code you have and the need to use
IOUtils.closeQuietly
.Now, you example:
Can be written as:
It's important to note that in order to use the try-with-resource approach, your resource need to implement a new interface called java.lang.AutoCloseable that was introduced in Java 7.
Also, you can include a number of resources in a try-with-resource block, just separate them with
;
The code should look like this regarding to the javadoc of
closeQuietly()
:closeQuietly()
is not intended for general use instead of callingclose()
directly on a Closable. Its intended use-case is for ensuring the close inside a finally-block - all error handling you need have to be done BEFORE that.That means, if you want to react on Exceptions during the call of
close()
orflush()
then you've to handle it the normal way. AddingcloseQuietly()
in your finally-block just ensures the close, e.g. when the flush failed and close was not called in try-block.It is safe so long as your application doesn't care whether the write succeeded without error. If your application needs to handle write errors it is not safe as buffered data flushed on close may be lost and the error swallowed.
It is possible in theory but I can't say I have ever seen close() fail. Usually fail fast means that a previous IO operations such as opening the file will fail first. You can write a close which doesn't ignore IOExceptions but this could clobber the true cause of an exception if it is something in the try/catch block which failed.
What you want is something like the following (which is overkill in most cases)