The difference and comparison between Java NiO and IO

Source: Internet
Author: User
Tags response code

Guide
j2se1.4 The new I/O class libraries are released in the previous release. In this article, we will briefly introduce some of the new features offered by the NIO Library: non-blocking I/O, character conversion, buffering, and channels.

I. Introduction of NIO
The NIO package (java.nio.*) introduces four key abstract data types that work together to address some of the problems in traditional I/O classes.
1 . Buffer: It is a linear table structure that contains data and is used for reading and writing. It also provides a special class for I/O operations for memory-mapped files.
2 . Charset: It provides the operation of a Unicode string that is mapped to a sequence of bytes and inverse innuendo.
3 . Channels: Contains the socket,file and pipe three kinds of pipes, it is actually two-way communication channel.
4 . Selector: It centralizes multiple asynchronous I/O operations into one or more line approached (it can be seen as an object-oriented version of the Select () function in Unix or waitforsingleevent () function in Win32).
Two. Recalling the traditional
Before introducing NIO, it is necessary to understand the traditional way of I/O operations. In the case of network applications, the traditional way to listen to a serversocket is to accept the requested connection to serve it (the service typically involves processing the request and sending a response). Figure one is the life cycle diagram of the server, where the part labeled with the thick black line indicates that I/O blocking occurs.


Figure A


you can analyze each specific step of creating a server. First createServerSocket
ServerSocket server=new ServerSocket (10000);
then accept the new connection request
Socket newconnection=server.accept ();
calls to the Accept method will cause blocking until ServerSocket accepts a connection request. Once the connection request is accepted, the server can read the request in the client socket.
InputStream in = Newconnection.getinputstream ();
InputStreamReader reader = new InputStreamReader (in);
BufferedReader buffer = new BufferedReader (reader);
Request Request = new request ();
while (!request.iscomplete ()) {
String line = Buffer.readline ();
Request.addline (line);
}
There are two problems with this operation, first the ReadLine () method of the BufferedReader class causes the thread to block when its buffer is not full, and only if certain data fills the buffer or the client closes the socket, the method returns. Second, it generates a lot of garbage, BufferedReader creates buffers to read data from client sockets, but also creates some strings to store the data. Although BufferedReader internally provides stringbuffer to deal with this problem, all of the strings quickly become garbage that needs to be recycled.
the same problem also exists in the Send response code
Response Response = Request.generateresponse ();
OutputStream out = Newconnection.getoutputstream ();
InputStream in = Response.getinputstream ();
int CH;
While ( -1! = (ch = in.read ())) {
Out.write (CH);
}
Newconnection.close ();
Similarly, read and write operations are blocked and writing one character at a time to the stream can be inefficient, so buffers should be used, but once the buffer is used, the stream generates more garbage.
the traditional way of solving
blocking I/O is typically handled in Java using threads (a large number of threads). A thread pool is typically implemented to handle requests, and two


Figure II
threads allow the server to handle multiple connections, but they also cause many problems. Each thread has its own stack space and consumes a bit of CPU time, is expensive, and spends a lot of time on blocking I/O operations, without effectively using the CPU.
three. NewI/O
1. Buffer
Traditional I/O is a constant waste of object resources (usually string). New I/O avoids resource wastage by reading and writing data using buffer. A buffer object is a linear, ordered collection of data that contains only a unique data type, depending on its category.
Java.nio.Bufferclass Description
Java.nio.ByteBuffer contains the byte type. Can be read from the Readablebytechannel in the Writablebytechannel write
The java.nio.MappedByteBuffer contains a byte type that maps directly to an area of memory
Java.nio.CharBuffer contains a character type and cannot be written to a channel
Java.nio.DoubleBuffer contains a double type and cannot be written to the channel
Java.nio.FloatBuffer contains float type
Java.nio.IntBuffer contains the int type
Java.nio.LongBuffer contains a long type
Java.nio.ShortBuffer contains the short type
You can assign a buffer by calling the allocate (int capacity) method or the Allocatedirect (int capacity) method. Specifically, you can create mappedbytesbuffer by calling Filechannel.map (int mode,long position,int size). Direct Buffer allocates a contiguous block in memory and reads and writes data using local access methods. The non-direct (nondirect) buffer reads and writes data by using the array access code in Java. Sometimes it is necessary to use non-direct buffering such as using any wrap method (such as Bytebuffer.wrap (byte[])) to create a buffer on the basis of a Java array.
2. Character encoding
storing data into Bytebuffer involves two questions: the order of bytes and the conversion of a character. The Bytebuffer internally handles byte order problems through the Byteorder class, but does not handle character conversions. In fact, Bytebuffer does not provide a way to read and write String.
Java.nio.charset.CharsetThe character conversion problem is handled. It converts character sequences into byte and inverse conversions by constructing charsetencoder and Charsetdecoder.
3. Channel(Channel)
You may notice that none of the existing java.io classes can read and write to the buffer type, so the channel class is provided in NiO to read and write buffer. A channel can be thought of as a connection, either to a particular device, to a program, or to a network. The class hierarchy chart for the channel is as follows


Might
Readablebytechannel and Writablebytechannel are used for reading and writing respectively.
Gatheringbytechannel you can write data from more than one buffer at once to the channel, instead, Scatteringbytechannel can read the data from the channel into multiple buffer at once. You can also set the channel to be a blocking or non-blocking I/O operation service.
to enable the channel to be compatible with traditional I/O classes, the Channel class provides a static method to create a stream or Reader
4. Selector
In the past blocking I/O, we generally know when to read or write to the stream because the method call is returned when the stream is ready. But with non-blocking channels, we need some way to know when the channel is ready. In the NIO package, the design of the selector is for this purpose. Selectablechannel can register a specific event instead of notifying the app when an event occurs, and the channel trace event. Then, when the app calls any of the selection methods on selector, it looks at the registered channel to see if any events of interest occur. Figure IV is an example of a selector and two registered channels


Figure Four
Not all channels are supported for all operations. The Selectionkey class defines all possible operation bits, which will be used two times. First, when the application calls the Selectablechannel.register (Selector sel,int op) method to register a channel, it passes the desired action to the method as the second parameter. Then, once Selectionkey is selected, the Selectionkey's Readyops () method returns the digits of all channels that support the operation. The Selectablechannel Validops method returns the operations allowed for each channel. An operation that is not supported by the registration channel throws an IllegalArgumentException exception. The following table lists the operations supported by the Selectablechannel subclass.

Serversocketchannel op_accept
Socketchannel Op_connect, Op_read, Op_write
Datagramchannel Op_read, Op_write
Pipe.sourcechannel Op_read
Pipe.sinkchannel Op_write

Four. Illustrative examples
1 . Simple Web content Download
This example is very simple, and class Socketchannelreader uses Socketchannel to download the HTML content of a particular Web page.
Package Examples.nio;

Import Java.nio.ByteBuffer;
Import Java.nio.channels.SocketChannel;
Import Java.nio.charset.Charset;
Import java.net.InetSocketAddress;
Import java.io.IOException;

public class socketchannelreader{

Private Charset Charset=charset.forname ("UTF-8");// create UTF-8 Character Set
Private Socketchannel channel;

public void Gethtmlcontent () {
try{
Connect ();
SendRequest ();
Readresponse ();
}catch (IOException e) {
System.err.println (e.tostring ());
} finally{
if (channel!=null) {
try{
Channel.close ();
} catch (IOException e) {}
}
}
}
private void Connect () throws ioexception{// connect to csdn
inetsocketaddress socketaddress=
New Inetsocketaddress ("/HTTP/ Www.csdn.net ", 80/);
Channel=socketchannel.open (socketaddress);
//Use the factory method open to create a channel and connect it to the specified address
// equivalent to Socketchannel.open (). Connect ( socketaddress); call
}

private void SendRequest () throws ioexception{
Channel.write (Charset.encode (" Get "
+"/document "
+" \r\n\r\n ");// send GET request to CSDN Document Center
// Use Channel.write method, which requires Charbyte type parameters, using
//charset.encode (String) method converts a string.
}

private void Readresponse () throws ioexception{// read answer
bytebuffer buffer=bytebuffer.allocate (1024x768);// Create a 1024-byte buffer
while (channel.read (buffer)!=-1) {
Buffer.flip ();//flip method is called before the read buffer byte operation.
system.out.println (Charset.decode (buffer));
convert bytes to strings using Charset.decode method
Buffer.clear ();// emptying buffer
}
}

public static void Main (String [] args) {
New Socketchannelreader (). Gethtmlcontent ();
}
2. Simple addition of servers and clients
Server code
Package Examples.nio;

Import Java.nio.ByteBuffer;
Import Java.nio.IntBuffer;
Import Java.nio.channels.ServerSocketChannel;
Import Java.nio.channels.SocketChannel;
Import java.net.InetSocketAddress;
Import java.io.IOException;

/**
* Sumserver.java
*
*
* Created:thu Nov 06 11:41:52 2003
*
* @author starchu1981
* @version 1.0
*/
public class Sumserver {

Private Bytebuffer _buffer=bytebuffer.allocate (8);
Private Intbuffer _intbuffer=_buffer.asintbuffer ();
Private Socketchannel _clientchannel=null;
Private Serversocketchannel _serverchannel=null;

public void Start () {
try{
Openchannel ();
Waitforconnection ();
}catch (IOException e) {
System.err.println (E.tostring ());
}
}

private void Openchannel () throws ioexception{
_serverchannel=serversocketchannel.open ();
_serverchannel.socket (). bind (New Inetsocketaddress (10000));
System.out.println (" server channel is already open ");
}

private void Waitforconnection () throws ioexception{
while (true) {
_clientchannel=_serverchannel.accept ();
if (_clientchannel!=null) {
System.out.println (" New Connection join ");
ProcessRequest ();
_clientchannel.close ();
}
}
}

private void ProcessRequest () throws ioexception{
_buffer.clear ();
_clientchannel.read (_buffer);
int result=_intbuffer.get (0) +_intbuffer.get (1);
_buffer.flip ();
_buffer.clear ();
_intbuffer.put (0,result);
_clientchannel.write (_buffer);
}

public static void Main (String [] args) {
New Sumserver (). Start ();
}
}//Sumserver
Customer Code
Package Examples.nio;

Import Java.nio.ByteBuffer;
Import Java.nio.IntBuffer;
Import Java.nio.channels.SocketChannel;
Import java.net.InetSocketAddress;
Import java.io.IOException;

/**
* Sumclient.java
*
*
* Created:thu Nov 06 11:26:06 2003
*
* @author starchu1981
* @version 1.0
*/
public class Sumclient {

Private Bytebuffer _buffer=bytebuffer.allocate (8);
Private Intbuffer _intbuffer;
Private Socketchannel _channel;

public sumclient () {
_intbuffer=_buffer.asintbuffer ();
}//Sumclient Constructor

public int getsum (int first,int second) {
int result=0;
try{
_channel=connect ();
Sendsumrequest (First,second);
Result=receiveresponse ();
}catch (IOException e) {System.err.println (e.tostring ());
} finally{
if (_channel!=null) {
try{
_channel.close ();
} catch (IOException e) {}
}
}
return result;
}

private Socketchannel Connect () throws ioexception{
Inetsocketaddress socketaddress=
New Inetsocketaddress ("localhost", 10000);
Return Socketchannel.open (socketaddress);
}

private void sendsumrequest (int first,int second) throws ioexception{
_buffer.clear ();
_intbuffer.put (0,first);
_intbuffer.put (1,second);
_channel.write (_buffer);
System.out.println (" Send addition request " + first+ "+" +second);
}

Private int receiveresponse () throws ioexception{
_buffer.clear ();
_channel.read (_buffer);
return _intbuffer.get (0);
}

public static void Main (String [] args) {
Sumclient sumclient=new sumclient ();
System.out.println (" addition results for :" +sumclient.getsum (100,324));
}
}//Sumclient
3 . Non-blocking addition server
First, add a statement to the Openchannel method
_serverchannel.configureblocking (FALSE);// set as non-blocking mode

The code for overriding the Waitforconnection method is as follows, using non-blocking methods
private void Waitforconnection () throws ioexception{
Selector acceptselector = Selectorprovider.provider (). Openselector ();

/* Register the selector on the server socket and set the notification to accept method.
This tells selector that the socket wants to be placed in the ready table when the Accept operation occurs
*/
Selectionkey acceptkey = Ssc.register (Acceptselector,
Selectionkey.op_accept);
int keysadded = 0; The

/*select method returns */
while (keysadded = Acceptselector.select ()) > 0) {
//a customer is ready for I/O operation, get its set of available keys
Set Readykeys = Acceptselector.selectedkeys ();
Iterator i = Readykeys.iterator ();

// traverse the Ready key collection and process the addition request
while (I.hasnext ()) {
Selectionkey SK = (Selectionkey) i.next ();
I.remove ();
Serversocketchannel nextready =
(Serversocketchannel) Sk.channel ();
Accept the addition request and process it
_clientsocket = Nextready.accept (). socket ();
ProcessRequest ();
_clientsocket.close ();
}
}
}

Resources
1 . <master Merlin ' s new I/O classes> from 2. j2se1.4.2 API specification from 3. <working with socketchannels> from 4. NIO Examples from

The difference and comparison between Java NiO and IO

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.