Skip to main content

PrintStream and PrintWriter

Java provides PrintStream and PrintWriter to write formatted data to a destination. The most famous example of a print stream is System.out, which is an instance of PrintStream.

Unlike most other output streams in Java, print streams are designed to be extremely developer-friendly, offering two major differences:

  1. They provide methods to print representations of all data types (like integers, floats, and custom objects) formatted as text.
  2. They never throw IOException. Instead, they catch these exceptions internally and set an internal status flag that you can query.

PrintStream vs. PrintWriter

  • PrintStream: A byte-based output stream. It writes character data by converting characters to bytes according to the default character encoding.
  • PrintWriter: A character-based writer. It is more robust for internationalized text handling because it natively understands charsets and character blocks.

For writing text reports or log files, PrintWriter is generally preferred over PrintStream.


Error Suppression

Print streams do not propagate standard IOExceptions during write operations. This prevents developers from having to wrap every simple System.out.println statement in a try-catch block.

If you need to verify whether a write operation failed (e.g. disk full, file locked, network interrupted), you can call the checkError() method:

try (PrintWriter writer = new PrintWriter("log.txt")) {
writer.println("Writing log entry...");
if (writer.checkError()) {
System.err.println("An error occurred during printing!");
}
}

Formatted Output: printf() / format()

Both PrintStream and PrintWriter support the printf() and format() methods, allowing you to format numbers, strings, and dates easily.

Common Format Specifiers

  • %s: String
  • %d: Integer (decimal)
  • %f: Floating-point number (e.g., %2f for 2 decimal places)
  • %b: Boolean
  • %n: Platform-independent newline character (always preferred over \n in formatted strings)

Practical Code Example: Writing a Formatted Report

The following example shows how to write a structured table report to a text file using PrintWriter and printf().

import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.IOException;

public class PrintStreamsDemo {
public static void main(String[] args) {
String filename = "report.txt";

// Wrap a FileWriter inside a PrintWriter
try (PrintWriter writer = new PrintWriter(new FileWriter(filename))) {

// Write a simple header
writer.println("=== COMPANY SALES REPORT ===");
writer.println("----------------------------------------");

// Format table headers: %-15s (left-aligned String, 15 chars), %10s (right-aligned)
writer.printf("%-15s %10s %12s%n", "Item Name", "Quantity", "Total Price");
writer.println("----------------------------------------");

// Write formatted rows
// %-15s: Left-aligned string
// %10d: Right-aligned decimal integer, 10 chars wide
// %12.2f: Right-aligned floating point, 12 chars wide, 2 decimal places
writer.printf("%-15s %10d %12.2f%n", "Laptop", 5, 4999.95);
writer.printf("%-15s %10d %12.2f%n", "Wireless Mouse", 12, 299.88);
writer.printf("%-15s %10d %12.2f%n", "Monitor 27\"", 3, 899.70);

writer.println("----------------------------------------");
writer.printf("%-15s %10s %12.2f%n", "TOTAL", "", 6199.53);

// Check if any error occurred during writing
if (writer.checkError()) {
System.err.println("Warning: An I/O error was suppressed during report generation.");
} else {
System.out.println("Report successfully written to " + filename);
}

} catch (IOException e) {
System.err.println("Could not open file writer: " + e.getMessage());
e.printStackTrace();
}
}
}