NIO support
The java.io
, java.nio
, and java.nio
subpackages provide most of the Java support for IO processing. We will examine the support that these packages provide for network access in Chapter 3, NIO Support for Networking. Here, we will focus on the basic aspects of the java.nio
package.
There are three key concepts used in the NIO package:
- Channel: This represents a stream of data between applications
- Buffer: This works with a channel to process data
- Selector: This is a technology that allows a single thread to handle multiple channels
A channel and a buffer are typically associated with each other. Data may be transferred from a channel to a buffer or from a buffer to a channel. The buffer, as its name implies, is a temporary repository for information. The selector is useful in supporting application scalability, and this will be discussed in Chapter 7, Network Scalability.
There are four primary channels:
FileChannel
: This works with a fileDatagramChannel
: This supports UDP communicationsSocketChannel
: This is used with a TCP clientServerSocketChannel
: This is used with a TCP server
There are several buffer classes that support primitive data types, such as character, integer, and float.
Using the URLConnection class
A simple way of accessing a server is to use the URLConnection
class. This class represents a connection between an application and a URL
instance. A URL
instance represents a resource on the Internet.
In the next example, a URL instance is created for the Google website. Using the URL
class' openConnection
method, a URLConnection
instance is created. A BufferedReader
instance is used to read lines from the connection that is then displayed:
try { URL url = new URL("http://www.google.com"); URLConnection urlConnection = url.openConnection(); BufferedReader br = new BufferedReader( new InputStreamReader( urlConnection.getInputStream())); String line; while ((line = br.readLine()) != null) { System.out.println(line); } br.close(); } catch (IOException ex) { // Handle exceptions }
The output is rather lengthy, so only part of the first line is shown here:
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" ...
The URLConnection
class hides some of the complexity of accessing HTTP servers.
Using the URLConnection class with buffers and channels
We can rework the previous example to illustrate the use of channels and buffers. The URLConnection
instance is created as before. We will create a ReadableByteChannel
instance and then a ByteBuffer
instance, as illustrated in the next example. The ReadableByteChannel
instance allows us to read from the site using its read
method. A ByteBuffer
instance receives data from the channel and is used as the argument of the read
method. The buffer created holds 64 bytes at a time.
The read
method returns the number of bytes read. The ByteBuffer
class' array
method returns an array of bytes, which is used as the argument of the String
class' constructor. This is used to display the data read. The clear
method is used to reset the buffer so that it can be used again:
try { URL url = new URL("http://www.google.com"); URLConnection urlConnection = url.openConnection(); InputStream inputStream = urlConnection.getInputStream(); ReadableByteChannel channel = Channels.newChannel(inputStream); ByteBuffer buffer = ByteBuffer.allocate(64); String line = null; while (channel.read(buffer) > 0) { System.out.println(new String(buffer.array())); buffer.clear(); } channel.close(); } catch (IOException ex) { // Handle exceptions }
The first line of output is shown next. This produces the same output as before, but it is restricted to displaying 64 bytes at a time:
<!doctype html><html itemscope="" itemtype="http://schema.org/We
The Channel
class and its derived classes provide an improved technique to access data found on a network than data provided by older technologies. We will be seeing more of this class.