Java Programming Handbook

    Java Reader and Writer Classes in Java

    In Java, when working with text-based input and output (character streams), the core classes to use are Reader and Writer. These are abstract classes provided in the java.io package that form the foundation for all character-based input and output operations.

    Class Hierarchy Diagram#

    java.lang.Object ├── java.io.Reader │ ├── BufferedReader │ ├── CharArrayReader │ ├── FilterReader │ ├── InputStreamReader │ │ └── FileReader │ ├── PipedReader │ ├── StringReader └── java.io.Writer ├── BufferedWriter ├── CharArrayWriter ├── FilterWriter ├── OutputStreamWriter │ └── FileWriter ├── PipedWriter ├── PrintWriter ├── StringWriter

    1. What Are Reader and Writer Classes?#

    • Reader: Abstract class for reading character streams.
    • Writer: Abstract class for writing character streams.

    They are used when working with text data, unlike InputStream and OutputStream which work with binary data.

    2. Reader Class Methods (With Examples)#

    int read()#

    Reads a single character. Returns -1 at the end of the stream.

    import java.io.*; public class ReaderReadExample { public static void main(String[] args) { try (Reader reader = new StringReader("Hello")) { int ch; while ((ch = reader.read()) != -1) { System.out.print((char) ch); // Prints each character } } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Hello

    Explanation: StringReader is used here to simulate a stream. It reads characters one by one.

    int read(char[] cbuf)#

    Reads characters into an array and returns the number of characters read.

    import java.io.*; public class ReaderReadArrayExample { public static void main(String[] args) { try (Reader reader = new StringReader("Java I/O")) { char[] buffer = new char[10]; int len = reader.read(buffer); System.out.println("Read characters: " + new String(buffer, 0, len)); } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Read characters: Java I/O

    void close()#

    Closes the reader and releases any associated system resources.

    import java.io.*; public class ReaderCloseExample { public static void main(String[] args) { try (Reader reader = new StringReader("Close Example")) { reader.read(); System.out.println("Reader closed automatically using try-with-resources"); } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Reader closed automatically using try-with-resources

    3. Writer Class Methods (With Examples)#

    void write(int c)#

    Writes a single character.

    import java.io.*; public class WriterWriteCharExample { public static void main(String[] args) { try (Writer writer = new FileWriter("output1.txt")) { writer.write(65); // Writes character 'A' System.out.println("Single character written."); } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Single character written.

    (File output1.txt contains: A)

    void write(char[] cbuf)#

    Writes an array of characters.

    import java.io.*; public class WriterWriteCharArrayExample { public static void main(String[] args) { char[] data = { 'J', 'a', 'v', 'a' }; try (Writer writer = new FileWriter("output2.txt")) { writer.write(data); System.out.println("Character array written."); } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Character array written.

    (File output2.txt contains: Java)

    void write(String str)#

    Writes an entire string.

    import java.io.*; public class WriterWriteStringExample { public static void main(String[] args) { try (Writer writer = new FileWriter("output3.txt")) { writer.write("Java Writer Example"); System.out.println("String written successfully."); } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    String written successfully.

    (File output3.txt contains: Java Writer Example)

    void flush()#

    Flushes the writer, forcing any buffered output to be written.

    import java.io.*; public class WriterFlushExample { public static void main(String[] args) { try (Writer writer = new FileWriter("output4.txt")) { writer.write("Flushed output."); writer.flush(); System.out.println("Output flushed."); } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Output flushed.

    void close()#

    Closes the stream and releases system resources.

    import java.io.*; public class WriterCloseExample { public static void main(String[] args) { try (Writer writer = new FileWriter("output5.txt")) { writer.write("Closing stream"); System.out.println("Writer closed using try-with-resources."); } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Writer closed using try-with-resources.

    4. When to Use Reader and Writer Classes?#

    • Use Reader when you want to read text data character by character or in chunks.
    • Use Writer when writing character data to a file, memory, or other output destinations.
    • For raw byte data like images or audio, prefer InputStream and OutputStream.

    Conclusion#

    In this blog, we learned about the Reader and Writer classes, the foundation of Java's character-based I/O system. We explored important methods such as read, write, flush, and close with clear examples, outputs, and practical usage. These classes pave the way for more advanced classes like BufferedReader, FileReader, PrintWriter, etc., which we’ll cover in upcoming blogs.

    Last updated on Apr 09, 2025