BufferedOutputStream does not throw I / O exception
When working on BufferedOutputStream
it doesn't throw IOException
when we wrote on it after closing the thread.
To test my result, I checked FileOutputStream
by finding that it throws IOException
after we try to write it after closing it.
public class Test {
public static void main(String[] args) {
try {
// Created a byte[] barry1 barry2
byte[] barry1 = { '1', '3' };
byte[] barray2 = { '2', '4' };
OutputStream os = new BufferedOutputStream(
new FileOutputStream("abc.txt", false));
// Writing to stream
os.write(barry1);
os.close();
os.write(barray2); // this suceeds - bug
os = new FileOutputStream("abc.txt", true);
//Writing to stream
os.write(barry1);
os.close();
os.write(barray2); // crashes here, correct.
} catch (Exception e) {
e.printStackTrace();
}
}
}
Can anyone help me on this why this behavior is different?
source to share
While working on BufferedOutputStream, I discovered that it does not throw an IOException when we wrote it after the stream was closed.
The code BufferedOutputStream
just doesn't have this type of validation, but neither does FileOutputStream
. In both cases, it is only when the IO is actually written to disk that the OS "throws" IOException
. It is not Java code that detects that the stream has been closed. As an aside, this probably means that some built-in implementations aren't thrown at all.
The reason it FileOutputStream
throws an exception in os.write(...)
versus BufferedOutputStream
is because it immediately writes the IO to the base layer. If you add a call os.flush()
to BufferedOutputStream
after os.write()
, then you will see the same exception, because that causes its internal buffer to be written out.
OutputStream os = new BufferedOutputStream(new FileOutputStream("abc.txt", false));
os.write(barry1);
os.close();
os.write(barray2); // this suceeds – unfortunate behavior
os.flush(); // adding this line throws an IOException
By accessing the method BufferedOutputStream
close()
(actually in the base class FilterOutputStream
), you can see that the output stream is not set to null
or something else:
public void close() throws IOException {
try {
flush();
} catch (IOException ignored) {
}
out.close();
}
I also don't like the fact that it ignores IOExceptions when closed here. Wow. This tells me that we always have to call flush()
manually before close()
, which I don't do on purpose. I did not do it.
Now compare this code with BufferedWriter.close()
:
public void close() throws IOException {
synchronized (lock) {
if (out == null) {
return;
}
try {
flushBuffer();
} finally {
out.close();
out = null; // good doggie
cb = null;
}
}
}
BufferedWriter.close()
does not use an exception and sets delegated Writer
as null
. Much better IMO.
source to share
Since it BufferedOutputStream
writes bytes to its internal byte buffer , then when called, it writes to the main ouput stream , so if the calls are reset after os.write(c);
, this will throw an exception, but here you are trying to write to the file stream immediately after it is closed, so the exception is not surprising here.
source to share