Java Programming Handbook

    Java StringReader and StringWriter Classes

    In Java, StringReader and StringWriter are part of the java.io package. Think of them as virtual readers and writers that operate on in-memory strings rather than physical files. Just like FileReader reads from a file or FileWriter writes to a file, StringReader reads from a string and StringWriter writes into a string. This is especially helpful when you want to simulate file I/O or work with strings using stream-based APIs without touching the filesystem.

    Imagine you're reading a story from a printed book — that's like using a FileReader. Now, think of reading the same story from a string saved in memory — that's where StringReader comes in. Similarly, instead of writing your thoughts to a notebook (like FileWriter), you write them into a digital sticky note stored in memory — that's what StringWriter does.

    These classes extend Reader and Writer respectively and are used for reading from and writing to strings as if they were input/output streams.

    1. Class Hierarchy#

    java.lang.Object ┛ java.io.Reader └── java.io.StringReader java.lang.Object ┛ java.io.Writer └── java.io.StringWriter
    • StringReader extends Reader
    • StringWriter extends Writer

    These are character-based stream classes that are especially useful for testing or when working with text in memory rather than with files.

    2. StringReader Class#

    StringReader allows you to read characters from a String source.

    ● Constructor#

    StringReader(String s)

    Creates a new StringReader using the specified string as the source.

    ● Example: Reading characters one by one#

    import java.io.*; public class StringReaderExample { public static void main(String[] args) { String data = "Hello, Java!"; // Create a StringReader from a string try (StringReader reader = new StringReader(data)) { int character; // Read one character at a time while ((character = reader.read()) != -1) { System.out.print((char) character); } } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Hello, Java!

    Explanation:#

    • read() reads one character at a time from the string source.
    • The loop continues until all characters are read.

    ● Example: Reading into a character array#

    import java.io.*; public class StringReaderBufferExample { public static void main(String[] args) { String content = "Buffered Read"; // Creating a character array buffer of size 20 // This will store the characters read from StringReader char[] buffer = new char[20]; try (StringReader reader = new StringReader(content)) { // Read characters into buffer starting at index 0 int charsRead = reader.read(buffer, 0, content.length()); System.out.println("Characters Read: " + new String(buffer, 0, charsRead)); } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Characters Read: Buffered Read

    Explanation:#

    • A char[] buffer is created to hold the characters read from the string.
    • The read(char[] cbuf, int off, int len) method fills the buffer from the string starting at the specified offset.
    • This approach is more efficient when reading large strings or reading multiple characters at once.

    ● close()#

    Automatically handled with try-with-resources but can also be closed manually.

    try (StringReader reader = new StringReader("Sample")) { // Operations } catch (IOException e) { e.printStackTrace(); } // reader is automatically closed here

    If not using try-with-resources:

    StringReader reader = new StringReader("Sample"); reader.close(); // manually close

    3. StringWriter Class#

    StringWriter allows you to write character data to a string buffer.

    ● Constructor#

    StringWriter() StringWriter(int initialSize)

    ● Example: Writing string content#

    import java.io.*; public class StringWriterExample { public static void main(String[] args) { // Creating a StringWriter try (StringWriter writer = new StringWriter()) { writer.write("Welcome to Java I/O"); // Writing to buffer String result = writer.toString(); // Get final string System.out.println("Written Content: " + result); } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Written Content: Welcome to Java I/O

    ● Example: Append characters and strings#

    import java.io.*; public class StringWriterAppendExample { public static void main(String[] args) { try (StringWriter writer = new StringWriter()) { writer.append('A'); // Appending a single character writer.append("ppend Example"); // Appending a string System.out.println("Appended Text: " + writer.toString()); } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Appended Text: Append Example

    ● getBuffer()#

    Returns the underlying StringBuffer used by the writer.

    import java.io.*; public class StringWriterBufferAccess { public static void main(String[] args) { try (StringWriter writer = new StringWriter()) { writer.write("Buffer Access"); StringBuffer buffer = writer.getBuffer(); System.out.println("Buffer: " + buffer); } catch (IOException e) { e.printStackTrace(); } } }

    Output:#

    Buffer: Buffer Access

    ● flush() and close()#

    flush() and close() are safe to call on a StringWriter, but they don't actually do anything. This is different from file-based streams like FileWriter, where flush() forces any buffered data to be written to the file and close() releases system resources. Since StringWriter writes to an in-memory buffer (a StringBuffer), there's no underlying resource to release or finalize. Therefore, calling flush() or close() won't change its behavior or output.

    StringWriter writer = new StringWriter(); writer.write("Example"); writer.flush(); // Has no real effect but safe to call writer.close(); // Also has no real effect System.out.println("Output: " + writer.toString());

    Output:#

    Output: Example

    These methods are safe to call but do not affect the internal buffer.

    4. When to Use StringReader and StringWriter#

    • StringReader:
      • When you need to simulate file reading from a string.
      • For unit testing methods that require a Reader input.
    • StringWriter:
      • When you want to gather output in memory instead of a file.
      • When you're dynamically building or modifying string content.

    Conclusion#

    StringReader and StringWriter are memory-based character stream classes. They are perfect for scenarios where you don't want to work with actual files but need the behavior of Reader and Writer. With clear syntax and familiar methods, they offer an efficient way to simulate file-like operations entirely in memory.

    Last updated on Apr 09, 2025