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?

+3


source to share


3 answers


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.

+4


source


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.



0


source


After inspecting the JDK code, it was found that the method ensureOpen()

that throws an IOException with a detailed "Stream closed" message is not present in the BufferedOutputStream. In my opinion it should be there.

0


source







All Articles