Java OutputStream Class
Last modified: April 16, 2025
The java.io.OutputStream
class is an abstract superclass representing
an output stream of bytes. It provides the fundamental methods needed for writing
data to various output destinations. All output stream classes inherit from this
base class.
OutputStream
defines the basic interface for byte output operations.
Concrete subclasses implement these methods for specific destinations like files,
network connections, or memory buffers. The class is part of Java's core I/O
system.
OutputStream Class Overview
OutputStream
is an abstract class that cannot be instantiated
directly. It provides the template for all byte output operations in Java. Key
methods include writing bytes, flushing buffers, and closing the stream.
public abstract class OutputStream implements Closeable, Flushable { public abstract 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 flush() throws IOException; public void close() throws IOException; }
The code above shows the key methods provided by OutputStream
. These
methods must be implemented by concrete subclasses. The class implements
Closeable
and Flushable
interfaces for resource
management.
Writing a Single Byte
The most basic operation is writing a single byte to the output stream. The
write(int b)
method writes the lowest 8 bits of the integer
argument. Higher bits are ignored. This is an abstract method that subclasses
must implement.
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class Main { public static void main(String[] args) { try (OutputStream os = new FileOutputStream("output.txt")) { // Write individual bytes os.write(72); // H os.write(101); // e os.write(108); // l os.write(108); // l os.write(111); // o System.out.println("Bytes written successfully"); } catch (IOException e) { e.printStackTrace(); } } }
This example demonstrates writing individual bytes to a file. The try-with-resources
statement ensures the stream is closed properly. Each write
call
outputs one byte to the stream. The bytes represent ASCII characters for "Hello".
Writing Byte Arrays
For better performance, you can write multiple bytes at once using byte arrays.
The write(byte[] b)
method writes all bytes in the array. There's
also a version that writes a portion of the array.
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class Main { public static void main(String[] args) { try (OutputStream os = new FileOutputStream("output.txt")) { // Create byte array byte[] data = "Hello, OutputStream!".getBytes(); // Write entire array os.write(data); // Write portion of array byte[] largeData = new byte[100]; System.arraycopy(data, 0, largeData, 0, data.length); os.write(largeData, 0, data.length); System.out.println("Byte arrays written successfully"); } catch (IOException e) { e.printStackTrace(); } } }
This example shows two ways to write byte arrays. First, the entire array is
written. Then, a portion of a larger array is written. The
System.arraycopy
method is used to copy data into the larger array.
This approach is more efficient than writing individual bytes.
Flushing the Output Stream
The flush
method forces any buffered output bytes to be written
out. Some output streams implement buffering for performance. Flushing ensures
data is actually written to the destination rather than sitting in a buffer.
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class Main { public static void main(String[] args) { try (OutputStream os = new BufferedOutputStream( new FileOutputStream("output.txt"))) { os.write("Important data".getBytes()); // Force write to disk os.flush(); System.out.println("Data written and flushed"); // More writes os.write("More data".getBytes()); } catch (IOException e) { e.printStackTrace(); } } }
This example demonstrates flushing a buffered output stream. The flush
call ensures the data is written to disk immediately. Without flushing, data might
remain in memory buffers until the stream is closed or the buffer fills. Flushing
is important for critical data.
Closing the Output Stream
The close
method releases system resources associated with the
stream. It's crucial to close streams to prevent resource leaks. The try-with-resources
statement automatically closes streams when the block exits.
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class Main { public static void main(String[] args) { OutputStream os = null; try { os = new FileOutputStream("output.txt"); os.write("Test data".getBytes()); System.out.println("Data written successfully"); } catch (IOException e) { e.printStackTrace(); } finally { if (os != null) { try { os.close(); System.out.println("Stream closed"); } catch (IOException e) { e.printStackTrace(); } } } } }
This example shows manual stream closing in a finally block. The stream is created outside try-with-resources to demonstrate proper manual closing. In practice, try-with-resources is preferred. Closing a stream automatically flushes any buffered data.
Using OutputStream with Buffering
For better performance, OutputStream
is often wrapped with
BufferedOutputStream
. This reduces the number of physical write
operations by buffering data in memory. The buffer is automatically flushed when
full or when the stream is closed.
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class Main { public static void main(String[] args) { try (OutputStream os = new BufferedOutputStream( new FileOutputStream("largefile.dat"), 8192)) { // Write 1MB of data byte[] data = new byte[1024]; // 1KB buffer for (int i = 0; i < 1024; i++) { // 1024 * 1KB = 1MB os.write(data); } System.out.println("1MB of data written with buffering"); } catch (IOException e) { e.printStackTrace(); } } }
This example demonstrates writing large amounts of data with buffering. The
BufferedOutputStream
uses an 8KB buffer (default is 8KB, but we
explicitly set it). Writing many small chunks is more efficient with buffering.
The buffer size can be tuned based on performance requirements.
Source
Java OutputStream Class Documentation
In this article, we've covered the essential methods and features of the Java OutputStream class. Understanding these concepts is crucial for working with output operations in Java applications.
Author
List all Java tutorials.