O'Reilly logo

Java RMI by William Grosso

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Readers and Writers

The last topics I will touch on in this chapter are the Reader and Writer abstract classes. Readers and writers are like input streams and output streams. The primary difference lies in the fundamental datatype that is read or written; streams are byte-oriented, whereas readers and writers use characters and strings.

The reason for this is internationalization. Readers and writers were designed to allow programs to use a localized character set and still have a stream-like model for communicating with external devices. As you might expect, the method definitions are quite similar to those for InputStream and OutputStream. Here are the basic methods defined in Reader:

public void close(  )
public void mark(int readAheadLimit) 
public boolean markSupported(  ) 
public int read(  ) 
public int read(char[] cbuf) 
public int read(char[] cbuf, int off, int len) 
public boolean ready(  ) 
public void reset(  ) 
public long skip(long n)

These are analogous to the read( ) methods defined for InputStream. For example, read( ) still returns an integer. The difference is that, instead of data values being in the range of 0-255 (i.e., single bytes), the return value is in the range of 0-65535 (appropriate for characters, which are 2 bytes wide). However, a return value of -1 is still used to signal that there is no more data.

The only other major change is that InputStream’s available( ) method has been replaced with a boolean method, ready( ), which returns true if the next call to read( ) doesn’t block. Calling ready( ) on a class that extends Reader is analogous to checking (available( ) > 0) on InputStream.

There aren’t nearly so many subclasses of Reader or Writer as there are types of streams. Instead, readers and writers can be used as a layer on top of streams—most readers have a constructor that takes an InputStream as an argument, and most writers have a constructor that takes an OutputStream as an argument. Thus, in order to use both localization and compression when writing to a file, open the file and implement compression by layering streams, and then wrap your final stream in a writer to add localization support, as in the following snippet of code:

FileOutputStream destination = new FileOutputStream(fileName);
BufferedOutputStream bufferedDestination = new BufferedOutputStream(destination);
GZIPOutputStream zippedDestination = new GZIPOutputStream(bufferedDestination);
OutputStreamWriter destinationWriter = new OutputStreamWriter(zippedDestination);

Revisiting the ViewFile Application

There is one very common Reader/Writer pair: BufferedReader and BufferedWriter. Unlike the stream buffering classes, which don’t add any new functionality, BufferedReader and BufferedWriter add additional methods for handling strings. In particular, BufferedReader adds the readLine( ) method (which reads a line of text), and BufferedWriter adds the newLine( ) method, which appends a line separator to the output.

These classes are very handy when reading or writing complex data. For example, a newline character is often a useful way to signal “end of current record.” To illustrate their use, here is the action listener from ViewFileFrame, rewritten to use BufferedReader:

private class ViewFileAction extends AbstractAction {
public void actionPerformed(ActionEvent event) {
		FileReader fileReader = _fileTextField.getFileReader(  );
		 if (null==fileReader) {
			_fileViewingArea.setText("Invalid file name");
		}
		else {
			try {
				copyReaderToViewingArea(fileReader);
				fileReader.close(  );
		 	}
			 catch (java.io.IOException ioException) {
				_fileViewingArea.setText("\n Error occured while reading file");
			 }
		 }
	}

	private void copyReaderToViewingArea(Reader reader) throws IOException {
		BufferedReader bufferedReader = new BufferedReader(reader);
		 String nextLine;
		 _fileViewingArea.setText("");
		while( null != (nextLine = bufferedReader.readLine(  ))) {

			_fileViewingArea.append(nextLine + "\n");
		}



	}

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required