jump to navigation

NIO August 6, 2005

Posted by Coolguy in J2SE.
trackback
  • NIO provides high-speed, block-oriented I/O in standard Java code
  • NIO moves the most time-consuming I/O activities (namely, filling and draining buffers) back into the operating system, thus allowing for a great increase in speed.
  • The most important distinction between the original I/O library (found in java.io.*) and NIO has to do with how data is packaged and transmitted.
  • Original I/O deals with data in streams, whereas NIO deals with data in blocks.
  • A stream-oriented I/O system deals with data one byte at a time. An input stream produces one byte of data, and an output stream consumes one byte of data
  • Stream-oriented I/O is often rather slow
  • A block-oriented I/O system deals with data in blocks. Each operation produces or consumes a block of data in one step. Processing data by the block can be much faster than processing it by the (streamed) byte
  • Channels and Buffers are the central objects in NIO, and are used for just about every I/O operation.
  • Channels are analogous to streams in the original I/O package. All data that goes anywhere (or comes from anywhere) must pass through a Channel object
  • A Buffer is essentially a container object. All data that is sent to a channel must first be placed in a buffer; likewise, any data that is read from a channel is read into a buffer.

Buffer

  • Buffer is an object, which holds some data, that is to be written to or that has just been read from.
  • In stream-oriented I/O, you wrote data directly to, and read data directly from, Stream objects.
  • In the NIO library, all data is handled with buffers. When data is read, it is read directly into a buffer. When data is written, it is written into a buffer. Anytime you access data in NIO, you are pulling it out of the buffer.
  • A buffer is essentially an array. Generally, it is an array of bytes, but other kinds of arrays can be used
  • A buffer provides structured access to data and also keeps track of the system’s read/write processes.
  • The most commonly used kind of buffer is the ByteBuffer. A ByteBuffer allows get/set operations (that is, the getting and setting of bytes) on its underlying byte array.
  • Types of buffers are:
  • ByteBuffer
    CharBuffer
    ShortBuffer
    IntBuffer
    LongBuffer
    FloatBuffer & DoubleBuffer
  • Each of the Buffer classes is an instance of the Buffer interface.
  • Two important components of buffers in NIO are state variables and accessor methods.
  • With each read/write operation, the buffer’s state changes. By recording and tracking those changes, a buffer is able to internally manage its own resources
  • When you read data from a channel, the data is placed in a buffer. In some cases, you can write this buffer directly to another channel, but often, you’ll want to look at the data itself. This is accomplished using the accessor method get(). Likewise, when you want to put raw data in a buffer, you use the accessor method put().

Channel

  • A Channel is an object from which you can read data and to which you can write data. Comparing NIO with original I/O, a channel is like a stream.
  • You never write a byte directly to a channel; instead you write to a buffer containing one or more bytes. Likewise, you don’t read a byte directly from a channel; you read from a channel into a buffer, and then get the bytes from the buffer.
  • Channels differ from streams in that they are bi-directional.
  • Whereas streams only go in one direction (a stream must be a subclass of either InputStream or OutputStream), a Channel can be opened for reading, for writing, or for both.
  • Because they are bi-directional, channels better reflect the reality of the underlying operating system than streams do. In the UNIX model in particular, the underlying operating system channels are bi-directional.

Reading from a file

  • Reading from a file involves three steps: (1) getting the Channel from FileInputStream; (2) creating the Buffer; and (3) reading from the Channel into the Buffer
  • FileInputStream fin = new FileInputStream( “readandshow.txt” );
  • FileChannel fc = fin.getChannel();
  • ByteBuffer buffer = ByteBuffer.allocate( 1024 );
  • fc.read( buffer );

Writing to a file

  • FileOutputStream fout = new FileOutputStream( “writesomebytes.txt” );
  • FileChannel fc = fout.getChannel();
  • ByteBuffer buffer = ByteBuffer.allocate( 1024 );
  • for (int i=0; i
  • { buffer.put( message[i] ); }
  • buffer.flip();
  • fc.write( buffer );

Asynchronous I/O

  • Asynchronous I/O is a method for reading and writing data without blocking. Normally, when your code makes a read() call, the code blocks until there is data to be read. Likewise, a write() call will block until the data can be written.
  • Asynchronous I/O calls, on the other hand, do not block. Instead, you register your interest in a particular I/O event — the arrival of readable data, a new socket connection, and so on — and the system tells you when such an event occurs.
  • One of the advantages of asynchronous I/O is that it lets you do I/O from a great many inputs and outputs at the same time.
  • Synchronous programs often have to resort to polling, or to the creation of many, many threads, to deal with lots of connections.
  • With asynchronous I/O, you can listen for I/O events on an arbitrary number of channels, without polling and without extra threads.
  • A server’s ability to handle numerous client requests within a reasonable time is dependent on how effectively it uses I/O streams. A server that caters to hundreds of clients simultaneously must be able to use I/O services concurrently.
  • Until JDK 1.4 (aka Merlin), the Java platform did not support nonblocking I/O calls. With an almost one-to-one ratio of threads to clients, servers written in the Java language were susceptible to enormous thread overhead, which resulted in both performance problems and lack of scalability.
  • Selectors and Channels were introduced to counter this issue
  • A Channel class represents a communication mechanism between a server and a client.
  • Selector class is a multiplexor of Channels. It demultiplexes incoming client requests and dispatches them to their respective request handlers.
  • A Selector is where you register your interest in various I/O events, and it is the object that tells you when those events occur.

Examples:

https://www6.software.ibm.com/developerworks/education/j-nio/j-nio-9-5.html

http://www-128.ibm.com/developerworks/java/library/j-javaio/

http://www-128.ibm.com/developerworks/library/j-nioserver/

https://www6.software.ibm.com/developerworks/education/j-nio/index.html

  • ServerSocketChannel ssc = ServerSocketChannel.open();
  • ssc.configureBlocking( false );
  • ServerSocket ss = ssc.socket();
  • InetSocketAddress address = new InetSocketAddress( ports[i] );
  • ss.bind( address );
  • …….

Advertisements

Comments»

No comments yet — be the first.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: