Question

I've come across a problem using FileOutputStream and BufferedWriter in Java.

If my disk space is full and I'm trying to write, it will throw IOException (which is correct), but when calling the writer.close(), it will fail to close the resource, throwing another IOException and keeping the resource opened!

Here is my workaround with writer.flush(). It seems to work, but is there a better way to handle this?

BufferedWriter writer = null;

    try {
         writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), encoding));
         StringBuilder buff = new StringBuilder();
         writeToStream(buff, separator, data);
         writer.write(buff.toString());
         writer.flush(); // flush before closing to make sure there is enough space on disk to complete the close()
         logger.trace("writeFile: file written, file={}", file);
    } catch (IOException e) {
         logger.error("writeFile: cannot write to file: {}", file, e);
         throw new ... //some exception wrapper here
    } finally {
         if (writer != null) {
               try {
                     writer.close();
               } catch (IOException e) {
                     // ignore
               }
          }
     }
Was it helpful?

Solution

You should try and close all resources in the reverse order in which you have opened them. Here you try and close only one.

If you have Java 7, use the try-with-resources statement. If you don't, the best way to do that is using Guava's Closer (available since version 14.0):

final Closer closer = Closer.create();
final FileOutputStream out;
final OutputStreamWriter writer;
final BufferedWriter buffered;

try {
    out = closer.register(new FileOutputStream(file), encoding));
    writer = closer.register(new OutputStreamWriter(out));
    buffered = closer.register(new BufferedWriter(writer));
    // do stuff
} catch (IOException e) {
    throw closer.rethrow(e);
} finally {
    closer.close();
}

If you don't have Closer, it is easy enough to recreate.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top