Interesting question.

I just peeked into each constructor's code, which helped clarify things:

FileWriter uses a FileOutputStream. The FileOutputStream throws a FileNotFoundException, which extends IOException.

FileWriter extends OutputStreamWriter whose constructor throws UnsupportedEncodingException, which also extends IOException.

FileWriter, therefore, can throw either exception. But since they both extend IOException, it declares IOException in its constructor's signature.

Answer from Keith on Stack Overflow
🌐
Oracle
docs.oracle.com › javase › 7 › docs › api › java › io › FileOutputStream.html
FileOutputStream (Java Platform SE 7 )
public final FileDescriptor getFD() throws IOException · Returns the file descriptor associated with this stream. Returns: the FileDescriptor object that represents the connection to the file in the file system being used by this FileOutputStream object. Throws: IOException - if an I/O error occurs.
🌐
Oracle
docs.oracle.com › en › java › javase › 11 › docs › api › java.base › java › io › FileOutputStream.html
FileOutputStream (Java SE 11 & JDK 11 )
January 20, 2026 - public final FileDescriptor getFD() throws IOException · Returns the file descriptor associated with this stream. Returns: the FileDescriptor object that represents the connection to the file in the file system being used by this FileOutputStream object. Throws: IOException - if an I/O error occurs.
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › io › FileOutputStream.html
FileOutputStream (Java Platform SE 8 )
March 16, 2026 - public final FileDescriptor getFD() throws IOException · Returns the file descriptor associated with this stream. Returns: the FileDescriptor object that represents the connection to the file in the file system being used by this FileOutputStream object. Throws: IOException - if an I/O error occurs.
🌐
Bug Database
bugs.java.com › bugdatabase › view_bug.do
Bug ID: JDK-4643434 FileOutputStream.writeBytes() throws IOException which omits disk name
For e.g. if the disk runs out of space while writing then, FileOutputStream class throw an IOException with the message "There is not enough space on the disk" but does not specify which disk.
Top answer
1 of 3
5

While working on BufferedOutputStream found it does not throw an IOException when we wrote on it after closing the stream.

The BufferedOutputStream code just doesn't have that sort of checking – but then neither does the FileOutputStream. In both cases, only when the IO is actually written to disk does the OS "throw" the IOException. It is not the Java code which is detecting that the stream has been closed. As an aside, this probably means that some native implementations don't throw at all.

The reason why the FileOutputStream is throwing the exception on os.write(...), versus the BufferedOutputStream, is that it is writing the IO to the underlying native layer immediately. If you add a os.flush() call to the BufferedOutputStream after the os.write() then you will see the same exception because that forces 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

In looking at the BufferedOutputStream's close() method (actually in the FilterOutputStream base class), you can see that the output stream is not set to null or anything:

public void close() throws IOException {
    try {
      flush();
    } catch (IOException ignored) {
    }
    out.close();
}

I also don't like the fact that it is ignoring IOExceptions on close here. Wow. This tells me that we should always call flush() by hand before close() which is a pattern I specifically don't do.

Now compare that code to the 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() doesn't eat the exception and sets the delegated Writer to be null. Much better IMO.

2 of 3
0

Because BufferedOutputStream writes bytes to its internal byte buffer, then when invoked writes to the underlying ouput stream, so if call flush after the os.write(c);, it will throw the exception, but here you try to write to the file stream directly after it was closed, hence the exception, no surprise here

Find elsewhere
🌐
C# Corner
c-sharpcorner.com › article › managing-io-files-in-java-with-fileoutputstream-fileinputstream
Managing IO Files in Java with FileOutputStream FileInputStream
July 25, 2024 - The write method of FileOutputStream is then used to write the byte array cities to the file. After writing, the close method is called to release the file resource. If an IOException occurs during this process, it is caught by the catch block, which prints the exception details and exits the program with a status of -1, indicating an error.
🌐
Stack Overflow
stackoverflow.com › questions › 17473614 › ioexception-closed-failed-on-fileoutputstream
java - IOException: closed failed on FileOutputStream - Stack Overflow
07-04 21:43:15.330: E/System(28070): Uncaught exception thrown by finalizer 07-04 21:43:15.330: E/System(28070): java.io.IOException: close failed: EIO (I/O error) 07-04 21:43:15.330: E/System(28070): at libcore.io.IoUtils.close(IoUtils.java:41) 07-04 21:43:15.330: E/System(28070): at java.io.FileOutputStream.close(FileOutputStream.java:139) 07-04 21:43:15.330: E/System(28070): at java.io.FileOutputStream.finalize(FileOutputStream.java:153) 07-04 21:43:15.330: E/System(28070): at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:186) 07-04 21:43:15.330: E/System(28070): at java.lang.Da
🌐
Oracle
docs.oracle.com › en › java › javase › 21 › docs › api › java.base › java › io › FileOutputStream.html
FileOutputStream (Java SE 21 & JDK 21)
January 20, 2026 - public final FileDescriptor getFD() throws IOException · Returns the file descriptor associated with this stream. Returns: the FileDescriptor object that represents the connection to the file in the file system being used by this FileOutputStream object. Throws: IOException - if an I/O error occurs.
🌐
Elastic
discuss.elastic.co › elastic observability › apm
Profiling_inferred_spans_enabled causes IOException: Input/output error when closing a filestream on a NAS server that uses Windows - APM - Discuss the Elastic Stack
November 10, 2020 - Kibana: 7.9 Elasticsearch: 7.9 Java 1.18.1 OS: Linux When profiling_inferred_spans_enabled is enabled java throws the following exception when closing a filestream: java.io.IOException: Input/output error at java.io.FileOutputStream.close0(Native Method) at java.io.FileOutputStream.access$000(FileOutputStream.java:53) at java.io.FileOutputStream$1.close(FileOutputStream.java:356) at java.io.FileDescriptor.closeAll(FileDescriptor.java:212) at java.io.FileOutputStream.close(FileOutputStr...
🌐
Greenfoot
greenfoot.org › topics › 63662 › 0
Greenfoot | Discuss | java.io.IOException Stream Closed
I was trying to do basic input output using FileInputStream and FileOutputStream , but it threw this error Please dont tell me why i am not using Scanner class for input , i was just trying out FileInputStream class Ok So This is the code: You can ignore the ShipPlayer , because that is just ...
🌐
W3Schools
w3schools.com › java › java_fileoutputstream.asp
Java FileOutputStream
import java.io.FileOutputStream; import java.io.IOException; public class Main { public static void main(String[] args) { String text = "\nAppended text!"; // true = append mode (keeps existing content) try (FileOutputStream output = new FileOutputStream("filename.txt", true)) { output.write(text.getBytes()); System.out.println("Successfully appended to file."); } catch (IOException e) { System.out.println("Error writing file."); e.printStackTrace(); } } }
🌐
CloudBees
cloudbees.com › blog › fileinputstream-fileoutputstream-considered-harmful
FileInputStream / FileOutputStream Considered Harmful
public void writeToFile(String fileName, byte[] content) throws IOException { try (FileOutputStream os = new FileOutputStream(fileName)) { os.write(content); } }
🌐
Ycpcs
ycpcs.github.io › cs201-fall2017 › notes › exceptionsFileIO.html
CS 201: Exceptions and File I/O
To read data from a file, you should create a FileInputStream object, passing a String containing the file name to FileInputStream’s constructor. The constructor for FileInputStream can throw IOException, which usually indicates that the file does not exist.
🌐
Stack Overflow
stackoverflow.com › questions › 39190624 › outputstreamwriter-ioexception-occurs
java - OutputStreamWriter IOException occurs - Stack Overflow
private static final String FILE_NAME="score.txt"; BufferedOutputStream o; try { o = new BufferedOutputStream(new FileOutputStream(new File(getFilesDir(),FILE_NAME))); String s = //here write what you want to write to the file . its got to be string to work o.write(s.getBytes()); o.close(); }catch (FileNotFoundException e ){ }catch (IOException e){ } for me its work for every time and its not opening new file every time.
🌐
GitHub
github.com › openjdk-mirror › jdk7u-jdk › blob › master › src › share › classes › java › io › FileOutputStream.java
jdk7u-jdk/src/share/classes/java/io/FileOutputStream.java at master · openjdk-mirror/jdk7u-jdk
* I/O on the stream, an <code>IOException</code> is thrown. * * @param fdObj the file descriptor to be opened for writing · * @exception SecurityException if a security manager exists and its · * <code>checkWrite</code> method denies · * write access to the file descriptor · * @see java.lang.SecurityManager#checkWrite(java.io.FileDescriptor) */ public FileOutputStream(FileDescriptor fdObj) { SecurityManager security = System.getSecurityManager(); if (fdObj == null) { throw new NullPointerException(); } if (security != null) { security.checkWrite(fdObj); } this.fd = fdObj; this.append = false; fd.attach(this); } ·
Author   openjdk-mirror