The java.io.StringReader
and
java.io.StringWriter
classes allow programmers to
use Reader
and Writer
methods
to read and write strings. Like char
arrays, Java
strings are also composed of pure Unicode characters. Therefore,
they’re good sources of data for readers and good targets for
writers. This is the other common case where readers and writers
don’t need to convert between different encodings.
This class would more accurately be called
StringBufferWriter
, but
StringWriter
is more poetic. A
StringWriter
maintains an internal
java.lang.StringBuffer
object to which written
characters are appended. This buffer can easily be converted to a
string as necessary.
public class StringWriter extends Writer
There is a single public constructor:
public StringWriter()
There is also a constructor that allows you to specify the initial size of the internal string buffer. This isn’t too important, because string buffers (and, by extension, string writers) are expanded as necessary. Still, if you can estimate the size of the string in advance, it’s marginally more efficient to select a size big enough to hold all characters that will be written. The constructor is protected in Java 1.1 and public in Java 2:
protected StringWriter(int initialSize) public StringWriter(int initialSize) // Java 2
The StringWriter
class has the usual collection of
write()
methods, all of which just append their
data to the StringBuffer
:
public void write(int c) public void write(char[] text, int offset, int length) public void write(String s) public void write(String s, int offset, int length)
There are flush()
and close()
methods, but both have empty method bodies, as string writers operate
completely internal to Java and do not require flushing or closing:
public void flush() public void close()
You can continue to write to a string writer even after it’s been closed. This should probably be classified as a bug, and I don’t recommend that you write code that relies on this behavior.
There are two ways to get the current contents of the
StringWriter
’s internal buffer. The
toString()
method returns it as a new
String
object, while the
getBuffer()
method returns the actual buffer:
public String toString() public StringBuffer getBuffer()
Strings are immutable, but changes to the buffer object returned by
getBuffer()
change the state of the
StringWriter
.
The following code fragment creates a string containing the printable ASCII character set:
StringWriter sw = new StringWriter(128); for (int i = 32; i < 127; i++) { sw.write(i); } String ascii = sw.toString();
A StringReader
uses the methods of the
Reader
class to get characters from a string. This
is useful when you want to process each character in a string in
sequential order. This class replaces the deprecated
StringBufferInputStream
class from Java 1.0:
public class StringReader extends Reader
The single constructor sets the string that’s the source of data for this reader:
public StringReader(String s)
Since string objects are immutable, the data in the string may not be
changed after the StringReader
is constructed. The
current position from which characters are read is stored in a
private field. Synchronization and thread safety are thus not major
problems for this class. Of course, the class has the usual
read()
methods, all of which read as many
characters as requested from the string:
public int read() throws IOException public int read(char[] buffer, int offset, int length) throws IOException
These methods return -1 if the end of the string has been reached.
They throw an IOException
if the reader has been
closed.
The skip()
method skips forward in the string the
specified number of places and returns the number of characters
skipped. It throws an IOException
if the reader is
closed.
public long skip(long n) throws IOException
The ready()
method returns
true
. Strings are always ready to be read.
public boolean ready() throws IOException
String readers support marking and resetting to the limit of the
string’s length. markSupported()
returns
true
. mark()
marks the current
position in the stream. (The readAheadLimit
argument is for compatibility only; its value is ignored.) The
reset()
method moves backward in the string to the
marked position.
public boolean markSupported() public void mark(int readAheadLimit) throws IOException public void reset() throws IOException
Finally, the close()
method sets the internal
string data to null
. Attempts to read from a
StringReader
after it’s been closed throw
IOException
s.
public void close()
Here’s a simple method that uses
StringReader
to break a string into its separate
characters and print them:
public static void printCharacters(String s) { StringReader sr = new StringReader(s); try { int c; while ((c = sr.read()) != -1) { System.out.println((char) c); } } catch (IOException e) {System.err.println(e);} return; }
Admittedly, this is a contrived example. If you really needed to do
this, you could just call the string’s
toCharArray()
method and loop through that (or
even the string itself) using its charAt()
method.
3.135.239.111