Does close ever throw an IOException?

I have found two cases:

  • Losing the network connection when there is still data in the buffer to be flushed.
  • Having the file system fill up (or reaching your user limit for file size) when there is still data in the buffer to be flushed.

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.

Leave a Comment