Java FileOutputStream Class
Last modified: April 16, 2025
The java.io.FileOutputStream
class is an output stream for writing
data to a file. It writes raw bytes to files and is part of Java's I/O package.
FileOutputStream is used for writing streams of bytes to files or file descriptors.
FileOutputStream
is typically wrapped in higher-level writers like
BufferedOutputStream
or PrintStream
for better
performance. It supports both append and overwrite modes for file writing.
This class is not thread-safe for concurrent access.
FileOutputStream Class Overview
FileOutputStream
extends OutputStream
and provides
basic file writing capabilities. Key methods include write operations for bytes
and byte arrays. The class handles file creation and opening automatically.
public class FileOutputStream extends OutputStream { public FileOutputStream(String name) throws FileNotFoundException; public FileOutputStream(String name, boolean append) throws FileNotFoundException; public FileOutputStream(File file) throws FileNotFoundException; public FileOutputStream(File file, boolean append) throws FileNotFoundException; public FileOutputStream(FileDescriptor fdObj); public void write(int b) throws IOException; public void write(byte[] b) throws IOException; public void write(byte[] b, int off, int len) throws IOException; public void close() throws IOException; public FileChannel getChannel(); public final FileDescriptor getFD() throws IOException; }
The code above shows key methods provided by FileOutputStream
.
These methods allow writing bytes to files in various ways. The class also
provides access to the underlying file channel and descriptor.
Creating a FileOutputStream
FileOutputStream can be created using file path strings, File objects, or file descriptors. The append parameter determines whether to overwrite or append to existing files. All constructors throw FileNotFoundException if the file cannot be opened.
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try { // Create with file path (overwrite mode) FileOutputStream fos1 = new FileOutputStream("output1.txt"); // Create with File object (append mode) File file = new File("output2.txt"); FileOutputStream fos2 = new FileOutputStream(file, true); System.out.println("FileOutputStream created (overwrite mode)"); System.out.println("FileOutputStream created (append mode)"); fos1.close(); fos2.close(); } catch (IOException e) { e.printStackTrace(); } } }
This example demonstrates different ways to create FileOutputStream. The first uses a file path and defaults to overwrite mode. The second uses a File object with append mode enabled. Always close streams when done to release resources.
Writing Single Bytes
The simplest write operation writes a single byte to the file. The byte is specified as an int, with only the lowest 8 bits written. This method is inefficient for bulk data but useful for specific cases.
import java.io.FileOutputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (FileOutputStream fos = new FileOutputStream("bytes.txt")) { // Write ASCII characters A-Z for (int i = 65; i <= 90; i++) { fos.write(i); } System.out.println("Bytes written successfully"); } catch (IOException e) { e.printStackTrace(); } } }
This example writes the ASCII characters A-Z to a file. Each character is written as a single byte. The try-with-resources statement ensures proper stream closure. Note that this approach is not suitable for Unicode characters outside ASCII range.
Writing Byte Arrays
For better performance, write multiple bytes at once using byte arrays. This reduces native I/O operations. The entire array or a portion can be written. This is the most efficient way to write bulk data.
import java.io.FileOutputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (FileOutputStream fos = new FileOutputStream("data.bin")) { // Create sample data byte[] data = new byte[256]; for (int i = 0; i < 256; i++) { data[i] = (byte) i; } // Write entire array fos.write(data); // Write portion of array fos.write(data, 0, 128); System.out.println("Byte arrays written successfully"); } catch (IOException e) { e.printStackTrace(); } } }
This example demonstrates writing byte arrays to a file. First, a 256-byte array is created and filled with values 0-255. The entire array is written, followed by just the first 128 bytes. This approach is much faster than writing individual bytes.
Appending to Files
FileOutputStream can append to existing files instead of overwriting them. This is controlled by the append parameter in constructors. Appending is useful for log files or when accumulating data.
import java.io.FileOutputStream; import java.io.IOException; public class Main { public static void main(String[] args) { String message = "Appended line\n"; try (FileOutputStream fos = new FileOutputStream("log.txt", true)) { // Append multiple messages for (int i = 1; i <= 5; i++) { String entry = i + ": " + message; fos.write(entry.getBytes()); } System.out.println("Messages appended to file"); } catch (IOException e) { e.printStackTrace(); } } }
This example shows how to append data to an existing file. The FileOutputStream is created with append mode enabled. Five log entries are written to the file. Each write operation adds to the end of the file rather than overwriting it.
Using FileChannel
FileOutputStream provides access to the underlying FileChannel. This allows for advanced file operations like file locking or memory-mapped I/O. The channel remains open until the stream is closed.
import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class Main { public static void main(String[] args) { try (FileOutputStream fos = new FileOutputStream("channel.txt"); FileChannel channel = fos.getChannel()) { String text = "Written using FileChannel"; ByteBuffer buffer = ByteBuffer.wrap(text.getBytes()); // Write through channel channel.write(buffer); System.out.println("Data written via FileChannel"); } catch (IOException e) { e.printStackTrace(); } } }
This example demonstrates using FileChannel from FileOutputStream. A ByteBuffer is created and filled with data. The channel writes the buffer contents to the file. This approach provides more control over file operations than the basic write methods.
Error Handling and Cleanup
Proper error handling is essential when working with file streams. Resources must be closed even if exceptions occur. Try-with-resources ensures proper cleanup. File operations should handle potential security and permission issues.
import java.io.FileOutputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (FileOutputStream fos = new FileOutputStream("important.dat")) { // Critical data writing byte[] criticalData = getCriticalData(); fos.write(criticalData); // Force write to disk fos.getFD().sync(); System.out.println("Critical data saved successfully"); } catch (IOException e) { System.err.println("Failed to write critical data: " + e.getMessage()); // Handle error appropriately } } private static byte[] getCriticalData() { // Simulate getting important data return "Very important information".getBytes(); } }
This example shows robust error handling for file operations. The try-with-resources ensures the stream is closed. The file descriptor's sync method forces data to disk. Errors are caught and handled appropriately. This pattern is recommended for production code.
Source
Java FileOutputStream Class Documentation
In this article, we've covered the essential methods and features of the Java FileOutputStream class. Understanding these concepts is crucial for working with file output operations in Java applications.
Author
List all Java tutorials.