After providing some answers here, and reading some comments, it would seem that, in practice IOException is never thrown on close for file I/O.
Are there any cases in which calling close on a Stream/Reader/Writer actually throws an IOException?
If an exception is actually thrown, how should it be dealt with?
In general, I/O means Input or Output. Those methods throw the IOException whenever an input or output operation is failed or interpreted. Note that this won't be thrown for reading or writing to memory as Java will be handling it automatically.
Error , Exception , and RuntimeException all have several subclasses. For example, IOException is a subclass of Exception and NullPointerException is a subclass of RuntimeException . You may have noticed that Java differentiates errors from exceptions.
IOException is the base class for exceptions thrown while accessing information using streams, files and directories. The Base Class Library includes the following types, each of which is a derived class of IOException : DirectoryNotFoundException. EndOfStreamException.
I have found two cases:
Both of those examples depend on something happening while there is still data in the buffer. Close flushes the buffer before the file is closes, so if there is an error writing the data to the file it throws an IOException.
If you execute the following code passing it the name of a file to create on a network drive, and then before you press the enter key unplug your network cable, it will cause the program to throw an IOException in close.
import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; public class Test { public static void main(final String[] argv) { final File file; file = new File(argv[0]); process(file); } private static void process(final File file) { Writer writer; writer = null; try { writer = new FileWriter(file); writer.write('a'); } catch(final IOException ex) { System.err.println("error opening file: " + file.getAbsolutePath()); } finally { if(writer != null) { try { try { System.out.println("Please press enter"); System.in.read(); } catch(IOException ex) { System.err.println("error reading from the keyboard"); } writer.close(); } catch(final IOException ex) { System.err.println("See it can be thrown!"); } } } } }
Since Java 7 you can use try-with-resources to get out of this mess (removed explicit exception generation code for the close()
operation):
private static void process(final File file) { try (final Writer writer = new FileWriter(file)) { writer.write('a'); } catch (final IOException e) { // handle exception } }
this will auto-magically handle the exceptions in close()
and it performs an explicit null
check internally.
When it does happen, it should be handled like any other IOException
, not silently ignored like you see recommended so often. The assumption is, I guess, that since you're done using the stream, it doesn't matter if it was cleaned up properly.
However, cleaning up properly is important. If a close()
operation does raise an exception, its likely that it involved flushing some output, committing some transaction (in the case of a database connection you thought was read-only), etc.—definitely not something that should be ignored. And, since it is rare, you're not compromising the reliability of your application significantly by aborting the operation.
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