The difference and comparison between Java NiO and IO

Source: Internet
Author: User
Tags response code

Guide
j2se1.4 The new I/O class library is advertised in the above version number. This article introduces some of the new features offered by the NIO library through some examples: non-clogging I/O, character conversion, buffering, and channels. I. IntroductionNIO
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 includes 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: Including the socket,file and pipe three pipes, it is actually a two-way communication channel.
4. Selector: It centralizes multiple asynchronous I/O operations into one or more line approached (it can be thought of as the object-oriented version number of the Select () function in Unix or the Waitforsingleevent () function in Win32).
two. Recall the traditional
before introducing NIO, it is necessary to understand the traditional way of I/O operations. As an example of a network application, the traditional way is to listen to a serversocket, accept the requested connection to serve it (the service usually contains the processing request and send a response) Figure one is the life cycle diagram of the server, and when the part of the thick black line is awarded it indicates that I/O congestion occurs.

Figure A
ability to analyze each detailed step of creating a server. First createServerSocket
ServerSocket server=new ServerSocket (10000);
then accept the new connection request
Socket newconnection=server.accept ();
the call to the Accept method will cause a blockage until ServerSocket accepts a connection request. Once the connection request is accepted, the server is able to 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 BufferedReader class's ReadLine () method will cause the thread to clog when its buffer is not full, only a certain amount of data fills the buffer or the client closes the socket, and the method returns. Second, it generates a lot of garbage, BufferedReader creates buffers to read data from client sockets, but the same creates some strings to store the data. Although BufferedReader internally provides stringbuffer to deal with this problem, all of the strings are quickly turned into 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 a lot of other garbage.
the traditional way of solving
It is common to use a thread (a large number of threads) to handle blocked I/O in Java. 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 a lot of problems. Each thread has its own stack space and consumes a bit of CPU time, is very expensive, and a lot of time is wasted on blocked I/O operations, without efficient CPU utilization.
three. NewI/O
1. Buffer
Traditional I/O is a constant waste of object resources (typically string). New I/O avoids resource wastage by reading and writing data using buffer. The buffer object is a linear, ordered collection of data that consists only of unique data types, depending on its category.
Java.nio.Bufferdescriptive Narrative of class
Java.nio.ByteBuffer includes byte types. Able to read from Readablebytechannel in Writablebytechannel
Java.nio.MappedByteBuffer includes byte types that map directly to an area of memory
Java.nio.CharBuffer include character type, cannot write to channel
Java.nio.DoubleBuffer includes double type, cannot write to channel
Java.nio.FloatBuffer includes float type
Java.nio.IntBuffer include int type
Java.nio.LongBuffer includes a long type
Java.nio.ShortBuffer includes 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 uses local access methods to read and write data. Non-direct (nondirect) buffer reads and writes data by using an array in Java to access the code. Sometimes it is necessary to use a non-direct buffer such as using a wrap method of whatever (such as Bytebuffer.wrap (byte[)) to create a buffer on a Java array basis.
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 feel a connection, a connection to a particular device, a program, or a network. The class hierarchy chart for a channel such as the following


Figure III
Readablebytechannel and Writablebytechannel are used for reading and writing respectively.
GatheringbytechannelThe ability to write data from more than one buffer at a time is written to the channel, whereas Scatteringbytechannel is able to read the data from the channel into multiple buffer at once. You can also set the channel to make it a clogged or non-clogging 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 orReader
4. Selector
In the past blocking I/O, we generally know when we can read or write to the stream, because the method call is returned when the stream is ready. But using a non-clogging channel, 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 is able to register specific events instead of notifying the app when an event occurs, channel tracking events. Then, when the app calls a random selection method on selector, it looks at the registered channel to see if there are any events of interest. Figure Four 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 the channel, it passes the desired action to the method as a second parameter. Then, once Selectionkey is selected, the Selectionkey's Readyops () method returns the digits of the full channel support operation. The Validops method of the Selectablechannel returns the operation that each channel agrees to. 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_writefour. Illustrative examples
1. Simple Web content Download
This example is easy, and class Socketchannelreader uses Socketchannel to download HTML content for 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");//creating the 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{//connected toCSDN
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
//quite with 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's document center
//using the Channel.write method, it needs to charbyte the type of the parameter, using the
//charset.encode (String)method to convert the 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 ();//flipmethod is called before the read buffer byte operation.
System.out.println (Charset.decode (buffer));
//Convert bytes to strings using the Charset.decode method
buffer.clear ();//Empty buffer
}
}public static void Main (String [] args) {
New Socketchannelreader (). Gethtmlcontent ();
}
2. Simple addition of server and client
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 ("The server channel is already open");
}private void Waitforconnection () throws ioexception{
while (true) {
_clientchannel=_serverchannel.accept ();
if (_clientchannel!=null) {
System.out.println ("new Connections Added");
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 an 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 ("The addition result is: "+sumclient.getsum (100,324));
}
}//Sumclient
3. Non-clogging addition server
First, add a statement to the Openchannel method
_serverchannel.configureblocking (FALSE);//set as non-clogging modethe code for overriding the Waitforconnection method, such as the following, uses 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 the acceptance method.
this tells selector that the socket wants to be placed in the ready table when the Accept operation occurs
on, therefore, agree that multivariate non-clogging I/O occurs. */
Selectionkey Acceptkey = Ssc.register (Acceptselector,
Selectionkey.op_accept);
int keysadded = 0;

The/*select method returns when an operation that has been registered on whatever*/
while ((keysadded = Acceptselector.select ()) > 0) {
A customer is ready to be able to perform I/O operations and gets 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 ();
}
}
} References
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 Http://blog.chinaunix.net/uid-24186189-id-2623973.html

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.