BufferedWriter.write does not throw exception if it is already closed.

Jing LV lvjing at linux.vnet.ibm.com
Tue Jan 25 14:45:35 UTC 2011


I find a problem in java.io.BufferedWriter. It is stated in the java
spec of its close() method:
"... Once the stream has been closed, further write() or flush()
invocations will cause an IOException to be thrown."
However if a BufferedWriter is created with a delegated writer, then it
seems to "forget" to throw IOException when it's closed, even if the
delegated writer wants to. Here is a simple example:

private int bufferSize = 1024;
public void test() throws Exception {
FailOnFlushWriter delegate = new FailOnFlushWriter();

Writer o = new BufferedWriter(delegate, bufferSize);
try {
// any of these is permitted to flush
fail("flush exception ignored");
} catch (IOException expected) {
assertEquals("Flush failed" , expected.getMessage());

try {
o.write("Hello World");
fail("expected already closed exception"); // failed here
} catch (IOException expected) {

private static class FailOnFlushWriter extends Writer {
boolean flushed = false;
boolean closed = false;

@Override public void write(char[] buf, int offset, int count) throws
IOException {
if (closed) {
throw new IOException("Already closed");

@Override public void close() throws IOException {
closed = true;

@Override public void flush() throws IOException {
if (!flushed) {
flushed = true;
throw new IOException("Flush failed");

If you run the testcases and it fails at once. By checking the code it
seems the BufferedWriter store the contents and do no real operation (as
its buffer size is 1024) and ignore the closed states - changing the
buffersize to be smaller like 10 would make the testcase passed . I
believe it would be a confusion for the user. Anyway, it would be easy
to fix.

Any comments?

More information about the core-libs-dev mailing list