Revisiting the ViewFile Application

public int readchar[] cbuf public int readchar[] cbuf, int off, int len public boolean ready public void reset public long skiplong 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 doesnt block. Calling ready on a class that extends Reader is analogous to checking available on InputStream . There arent 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 FileOutputStreamfileName; BufferedOutputStream bufferedDestination = new BufferedOutputStreamdestination; GZIPOutputStream zippedDestination = new GZIPOutputStreambufferedDestination; OutputStreamWriter destinationWriter = new OutputStreamWriterzippedDestination;

1.4.1 Revisiting the ViewFile Application

There is one very common Reader Writer pair: BufferedReader and BufferedWriter . Unlike the stream buffering classes, which dont 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 actionPerformedActionEvent event { FileReader fileReader = _fileTextField.getFileReader ; if null==fileReader { _fileViewingArea.setTextInvalid file name; } else { try { copyReaderToViewingAreafileReader; fileReader.close ; } catch java.io.IOException ioException { _fileViewingArea.setText\n Error occured while reading file; } } } private void copyReaderToViewingAreaReader reader throws IOException { BufferedReader bufferedReader = new BufferedReaderreader; String nextLine; _fileViewingArea.setText; while null = nextLine = bufferedReader.readLine { _fileViewingArea.appendnextLine + \n; } }

Chapter 2. Sockets

In this chapter, we review Javas socket classes. Sockets are an abstraction that allow two programs, usually on different machines, to communicate by sending data through streams. Strictly speaking, the socket classes which are defined in the java.net package are not part of RMI. However, RMI uses Javas socket classes to handle communication between distinct processes. Thus, a basic knowledge of how sockets work is fundamental to understanding RMI. This chapters coverage, though far from complete, constitutes the core of what an RMI programmer needs to know.

2.1 Internet Definitions

The Internet is built out of computers that are connected by wires. [ 1] Each wire serves as a way to exchange information between the two computers it connects. Information is transferred in small, discrete chunks of data called datagrams. [ 1] Or, in the case of wireless networks, things that behave like wires. Each datagram has a header and a data area. The header describes the datagram: where the datagram originated, what machines have handled the datagram, the type and length of the data being sent, and the intended destination of the the datagram. The data area consists of the actual information that is being sent. In almost all networking protocols, the data area is of limited size. For example, the Internet Protocol frequently referred to as IP restricts datagrams to 64 KB. The Internet Protocol is also an example of what is frequently called a connectionless protocol™ each datagram is sent independently, and there is no guarantee that any of the datagrams will actually make it to their destination. In addition, the sender is not notified if a datagram does not make it to the destination. Different datagrams sent to the same destination machine may arrive out of order and may actually travel along different paths to the destination machine. Connectionless protocols have some very nice features. Conceptually, theyre a lot like the postal service. You submit an envelope into the system, couriers move it around, and, if all goes well, it eventually arrives at the destination. However, there are some problems. First, you have no control over which couriers handle the envelope. In addition, the arrival time of the envelope isnt