String Readers and Writers

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 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.

20.7.1. String Writers

This class would more accurately be called StringBufferWriter, but StringWriter is more poetic. A StringWriter maintains an internal StringBuffer to which it appends characters. This buffer can easily be converted to a string as necessary. StringWriter has a no-args 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 more efficient to select a size big enough to hold all characters that will be written:

public StringWriter(int initialSize)

The StringWriter class has the usual collection of write( ) methods, all of which just append their data to the StringBuffer.

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. You can continue to write to a StringWriter 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( );

 

20.7.2. String Readers

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:

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.

Of course, the class has the usual read( ) methods, all of which read as many characters as requested from the string. These methods return -1 if the end of the string has been reached. They throw an IOException if the reader has been closed.

The ready( ) method returns TRue. Strings are always ready to be read.

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.

Finally, the close( ) method sets the internal string data to null. Attempts to read from a StringReader after it's been closed throw IOExceptions.

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 ex) { // should not happen; StringReaders do not throw exceptions } return; }

Admittedly, this is a contrived example. If you really needed to do this, you could just loop through the string itself using its charAt( ) method.

Категории