HOWTO · Java
How to Use the flush() Method in Java I/O
Learn how flush() passes buffered Java I/O output to the next layer, with examples using PrintWriter and BufferedOutputStream.
On this page
Java developers use flush() to move buffered output to the next layer when it needs to be available before the output object is closed. It belongs to Java I/O (Writer and OutputStream), not the Java Stream API for processing sequences. The call does not promise that a file is durable on disk or that a remote server has received or processed bytes.
What flush() Does in Java I/O
Output classes can collect writes in memory to reduce calls to the underlying destination. Calling flush() asks that output object to pass its pending data onward. With a BufferedOutputStream, for example, this sends the wrapper’s pending bytes to its wrapped stream. A downstream layer may buffer independently, so flushing one object does not necessarily empty every buffer in the chain. Flushing passes pending data onward and makes the buffering layer’s used capacity reusable, but it does not deallocate the buffer or guarantee downstream delivery or durable storage. Flushing alone also does not guarantee data integrity or protect against corrupted output; when integrity matters, use the checks required by your application, such as validating a checksum or message format.
Writers perform the corresponding operation for character output. A writer may encode characters into bytes as it passes data to a lower-level stream. The exact buffering behavior depends on the objects in the chain; flush() is useful when the program needs output to move onward now, rather than waiting for a later write or close.
When to Call flush()
Flush at a meaningful handoff point: for example, after writing a prompt before waiting for user input, after emitting a log record that another process should read promptly, or after sending a complete message through a buffered socket writer. If a program writes many small pieces to a file or another throughput-oriented destination, flushing each piece can defeat buffering and add overhead. Let normal buffering and resource closure handle output when intermediate visibility is not needed.
Using flush() with a Writer
This self-contained Java example writes through a BufferedWriter and PrintWriter to a StringWriter. The printed value is the text available in the destination after the explicit flush.
Run this example:
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
public class FlushWriterExample {
public static void main(String[] args) throws java.io.IOException {
StringWriter destination = new StringWriter();
try (PrintWriter writer = new PrintWriter(new BufferedWriter(destination))) {
writer.println("status=ready");
writer.flush();
System.out.print(destination.toString());
}
}
}
status=ready
The BufferedWriter makes the buffering layer explicit. Flushing the outer PrintWriter passes its characters through that writer to the StringWriter; printing the destination then shows the resulting line. StringWriter is an in-memory destination for a compact demonstration, while a file or socket writer has different downstream behavior.
Using flush() with a BufferedOutputStream
For byte output, flush the buffering wrapper when its pending bytes should be handed to the wrapped stream. This standalone example uses an in-memory byte destination, so it needs no file or service.
import java.io.ByteArrayOutputStream;
import java.io.BufferedOutputStream;
import java.nio.charset.StandardCharsets;
public class BufferedFlushExample {
public static void main(String[] args) throws java.io.IOException {
ByteArrayOutputStream destination = new ByteArrayOutputStream();
try (BufferedOutputStream output = new BufferedOutputStream(destination)) {
output.write("batch-42".getBytes(StandardCharsets.UTF_8));
output.flush();
System.out.println(new String(destination.toByteArray(), StandardCharsets.UTF_8));
}
}
}
batch-42
Here the wrapper passes the encoded bytes to the in-memory stream at flush(). With a file stream, this operation passes bytes to the operating system’s file layer; it does not by itself promise that storage hardware has committed them. For durable file data, use the appropriate file API and durability options for the application.
Using flush() with Network Output
When writing a request or message through a buffered socket writer, call flush() after the complete message if the peer is waiting for it. For instance, out.println("PING"); out.flush(); hands the line from the writer to the socket’s output path. This does not prove that the bytes reached the peer, were read, or were acted on. Use a protocol response or acknowledgment when the application needs confirmation, and handle socket errors and timeouts in the surrounding code. A network example requires a connected peer, so the short expression is illustrative rather than a standalone runnable program.
How flush() Relates to Closing a Stream
Closing an output stream or writer generally flushes it as part of closing. Use try-with-resources so the resource is closed even when later work exits early. An explicit flush before close is unnecessary when close is the next operation and no intermediate reader needs the data; it is useful when the program must expose output while keeping the resource open. Neither flush nor close guarantees protection from every application or system failure, so do not treat either as a substitute for the durability or acknowledgment guarantees your task requires.