Java NIO API Detailed

Source: Internet
Author: User
Tags abstract date aliases error handling flush connect socket thread
In detail before JDK 1.4, Java IO Operations were concentrated in the Java.io package and were based on the streaming synchronization (blocking) API. For most applications, such APIs are easy to use, however, some applications with high performance requirements, especially server applications, often require a more efficient way to process IO. From JDK 1.4, the NIO API is introduced as a buffer-based API that provides asynchronous (non-blocking) IO operations. This article carries on the thorough introduction to it.



The NIO APIs are mainly concentrated in the Java.nio and its subpackages:



Java.nio

Defines a subclass of buffer and its data type. The role of the bytebuffer that is used by classes in Java.nio.channels to perform IO operations is very important.



Java.nio.channels

Defines a series of channel interfaces that process IO and the implementation of these interfaces on file systems and network communications. By selector This class, it also provides a way to perform asynchronous IO operations. This package can be said to be the core of the NIO API.



Java.nio.channels.spi

Defines an abstract class that can be used to implement the channel and selector APIs.



Java.nio.charset

Defines a class that handles character encoding and decoding.



Java.nio.charset.spi

Defines an abstract class that can be used to implement the CharSet API.



Java.nio.channels.spi and Java.nio.charset.spi These two packages are mainly used to extend the existing NiO APIs, and in actual use, we typically only deal with another 3 packages. The 3 packages are described below.



Package Java.nio

This package mainly defines the buffer and its subclasses. Buffer defines a container interface for linearly storing primitive type data. For primitive types other than Boolean, there is a corresponding buffer subclass, and Bytebuffer is one of the most important subclasses.



The following UML class diagram describes the relationships of classes in Java.nio:






Buffer

Defines a container interface that can be primitive type data in a linear location. The buffer mainly contains the type (Byte, char ...). ) unrelated features. It is worth noting that the buffer and its subclasses are not thread-safe.



Each buffer has the following properties:



Capacity

The maximum amount of data this buffer can put. Capacity are typically specified when the buffer is created.

Limit

The read and write operation on the buffer cannot cross the subscript. When writing data to buffer, limit is generally equal to capacity, when reading data, limit represents the length of valid data in buffer.

Position

The current subscript for the read/write operation. When a read/write operation is performed using the relative position of buffer, the read/write is performed from the subscript, and after the operation completes, buffer updates the value of the object.

Mark

A temporary storage position subscript. Calling Mark () will set mark as the current position value, and later call Reset () sets the position property to mark's value. Mark's value is always less than or equal to the position value, and if the value of the position is set to be smaller than mark, the current mark value is discarded.



These properties always meet the following criteria:

0 <= Mark <= position <= limit <= capacity



The values of limit and position are set by the limit () and position () functions, or they can be changed by the following functions:



Buffer Clear ()

Set the position to 0 and set the limit to capacity, which is usually called before the data is written to buffer.

Buffer Flip ()

The limit is set to the current position, and the position is set to 0, which is usually called before the data is read from the buffer.

Buffer Rewind ()

The position is set to 0,limit, which is usually called before the data is rewritten into the buffer.



The buffer object may be read-only, and any write to the object will trigger a readonlybufferexception. The IsReadOnly () method can be used to determine whether a buffer is read-only.



Bytebuffer

In the subclass of buffer, Bytebuffer is a very special class, because the various channel IO operations defined in Java.io.channels are basically spread around the bytebuffer.



Bytebuffer defines 4 static methods for creating work:



Bytebuffer allocate (int capacity)

Creates a bytebuffer that specifies the capacity.

Bytebuffer allocatedirect (int capacity)

Create a direct bytebuffer that bytebuffer better performance when participating in IO operations (most likely at the bottom of the implementation using DMA technology), and correspondingly, the cost of creating and reclaiming direct Bytebuffer is higher. The Isdirect () method can check whether a buffer is direct.

Bytebuffer Wrap (Byte [] array)

Bytebuffer Wrap (Byte [] array, int offset, int length)

Wraps a byte array or part of a byte array into Bytebuffer.



Bytebuffer defines a series of get and put operations from which to read and write byte data, such as the following:



BYTE get ()

Bytebuffer get (Byte [] DST)

BYTE get (int index)



Bytebuffer put (Byte b)

Bytebuffer put (byte [] src)

Bytebuffer put (int index, byte b)



These operations can be divided into absolute positioning and relative to two, the relative positioning of the read and write operations rely on position to locate the buffer, and the operation is completed after the update position value.

In other types of buffer, the same function is defined to read and write data, and the only difference is the type of some parameters and return values.



In addition to the function of reading and writing byte data, one of the special bytebuffer is that it also defines methods for reading and writing other primitive data, such as:



int GetInt ()

Reads an int value from the Bytebuffer.

Bytebuffer putint (int value)

Writes an int value into the bytebuffer.



Reading and writing other types of data involves a byte-order problem, and Bytebuffer writes or reads a different type of data (Int,long ...) in its byte order (large byte order or small byte order). )。 The byte sequence can be obtained and set with the order method:



Byteorder order ()

Returns the byte order of the Bytebuffer.

Bytebuffer order (Byteorder Bo)

Sets the byte order of the Bytebuffer.



Another special place for Bytebuffer is to get other types of buffer on its basis. Such as:



Charbuffer Ascharbuffer ()

Creates a Charbuffer view for the current bytebuffer. The read and write operations in the view Buffer Act on the data in the Bytebuffer according to the Bytebuffer byte order.



The buffer created with such a method starts at the position position of the bytebuffer and ends at the limit position, which can be viewed as a view of the data. The readonly and direct properties of view buffer are consistent with the bytebuffer, and only in this way can you get direct buffer of other data types.



Byteorder

The class used to represent the Bytebuffer byte order, which can be viewed as an enum type in Java. The following several static methods and properties are mainly defined:



Byteorder Big_endian

A byteorder that represents a large byte sequence.

Byteorder Little_endian

Represents the byteorder of a small byte sequence.

Byteorder Nativeorder ()

Returns the byte order of the current hardware platform.



Mappedbytebuffer

A subclass of Bytebuffer is a mapping of the contents of a file in memory. An instance of this class needs to be created through the FileChannel map () method.





Let's take a look at an example of using Bytebuffer, which reads the characters from the standard input and writes the collected characters to the standard output when a full line is read:

public static void Main (String [] args)

Throws IOException

{

Create a bytebuffer with capacity 256

Bytebuffer buf = bytebuffer.allocate (256);

while (true) {

Read a character from the standard input stream

int c = System.in.read ();

Exit loop when read to end of input stream

if (c = = 1)

Break



Writes the read characters into the Bytebuffer

Buf.put ((byte) c);

Output collected characters when a row is read

if (c = = ' \ n ') {

Call Flip () to change the limit to the current position value, position to 0,

Prepare for next reading from Bytebuffer

Buf.flip ();

Building a byte array

byte [] content = new Byte[buf.limit ()];

Reading data from Bytebuffer to byte array

Buf.get (content);

Writes the contents of the byte array to the standard output

System.out.print (new String (content));

Call Clear () to make position into a value of 0,limit to capacity,

Prepare for next write data to Bytebuffer

Buf.clear ();

}

}

}






Package Java.nio.channels

This package defines the concept of channel, channel shows a channel that can be IO operated (for example, by FileChannel, we can read and write files). Java.nio.channels contains channel classes related to file systems and network communications. This package, through the two classes selector and Selectablechannel, also defines an API for asynchronous (non-blocking) IO operations, which is important for applications that require high-performance IO.



The UML class diagram below describes the relationship between interface in Java.nio.channels:






Channel

Channel shows an IO-capable channel that defines the following methods: interface



Boolean IsOpen ()

Whether the channel is open.

void Close ()

Close this channel and the associated resources will be released.



Readablebytechannel

Defines a channel interface from which byte data can be read.



int read (Bytebuffer DST)

Reads the byte data from the channel and writes it to the Bytebuffer. Returns the number of bytes read.



Writablebytechannel

Defines a channel interface that can write byte data to it.



int write (Bytebuffer src)

Reads the byte data from the Bytebuffer and writes it to the channel. Returns the number of bytes written.



Bytechannel

Bytechannel does not define a new method, its role is to merge Readablebytechannel and Writablebytechannel together.



Scatteringbytechannel

Inherits the Readablebytechannel and provides the ability to write data to several bytebuffer at the same time.



Gatheringbytechannel

Inherits Writablebytechannel and provides the ability to read data from several bytebuffer at the same time.



Interruptiblechannel

Used to represent a channel that can be closed asynchronously. This is manifested in two ways:

1. When a Interruptiblechannel close () method is invoked, the threads of other blocks on this interruptiblechannel IO operation receive a asynchronouscloseexception.

2. When one thread block is on a interruptiblechannel io operation, another thread calls the thread's interrupt () method to cause the channel to be closed, and the thread receives a closedbyinterruptexception , the interrupt state of the thread is set.





The next UML class diagram describes the relationships of classes in Java.nio.channels:






Asynchronous IO

Asynchronous IO support can be considered as the most important feature of the NIO API, which allows applications to monitor multiple channel simultaneously to improve performance, a feature that is implemented through the 3 classes of Selector,selectablechannel and Selectionkey.



Selectablechannel represents a channel that can support asynchronous IO operations and can be registered on selector, which is represented by the Selectionkey class (see UML diagram). Selector This class uses the Select () function to provide an application with a way to monitor multiple IO channel at the same time:



By invoking the Select () function, the application lets selector monitor multiple selectablechannel registered on it, and when a channel IO operation is available, the Select () method returns to allow the application to check the channel state. and make the corresponding treatment.



The following is an example of asynchronous IO in JDK 1.4, which uses asynchronous IO to implement a time server:

private static void acceptconnections (int port) throws Exception {

Open a Selector

Selector Acceptselector =

Selectorprovider.provider (). Openselector ();



Create a Serversocketchannel, this is a selectablechannel subclass

Serversocketchannel SSC = Serversocketchannel.open ();

Set it to non-blocking state so that asynchronous IO operations can be performed

Ssc.configureblocking (FALSE);



Socket binding IP and port to Serversocketchannel

InetAddress lh = Inetaddress.getlocalhost ();

Inetsocketaddress isa = new Inetsocketaddress (LH, Port);

Ssc.socket (). bind (ISA);



Register the Serversocketchannel on the selector and return the corresponding Selectionkey

Selectionkey Acceptkey =

Ssc.register (Acceptselector, selectionkey.op_accept);



int keysadded = 0;



Use the Select () function to monitor the Selectablechannel registered on the selector

The return value represents how many channel can be IO operated (ready for IO)

while ((keysadded = Acceptselector.select ()) > 0) {

Selectedkeys () returns a collection of Selectionkey,

Each of these selectionkey represents a channel that can perform IO operations.

A Serversocketchannel io operation means that a new TCP connection is connected to the

Set Readykeys = Acceptselector.selectedkeys ();

Iterator i = Readykeys.iterator ();



while (I.hasnext ()) {

Selectionkey SK = (Selectionkey) i.next ();

You need to remove the handled key from the Selectedkeys collection

I.remove ();

Get the corresponding channel from Selectionkey

Serversocketchannel Nextready =

(Serversocketchannel) Sk.channel ();

Accept a new TCP connection

Socket s = nextready.accept (). socket ();

Write the current time to this new TCP connection

PrintWriter out =

New PrintWriter (S.getoutputstream (), true);

Date now = new Date ();

Out.println (now);

Close connection

Out.close ();

}

}

}


This is a purely illustrative example, because only one serversocketchannel needs to be monitored, so it really doesn't need to use asynchronous IO. But just because it's simple, it's easy to see how asynchronous IO Works.



Selectablechannel

This abstract class is the parent class for all channel (such as Datagramchannel, Socketchannel) that support asynchronous IO operations. Selectablechannel can be registered on one or more selector for asynchronous IO operations.



Selectablechannel can be blocking and non-blocking modes (all channel are created in blocking mode), Only non-blocking Selectablechannel can participate in asynchronous IO operations.



Selectablechannel configureblocking (Boolean block)

Set blocking mode.

Boolean isblocking ()

Returns the blocking mode.



Through the Register () method, Selectablechannel can be registered on the selector.



int Validops ()

Returns a bit mask that represents the IO operation supported on this channel. Currently in Selectionkey, the bit values of 4 IO operations are defined with static constants: Op_accept,op_connect,op_read and Op_write.

Selectionkey Register (Selector sel, int ops)

Registers the current channel on a selector and returns the corresponding Selectionkey. After that, you can monitor the channel by calling the selector select () function. The OPS parameter is a bit mask that represents IO operations that need to be monitored.

Selectionkey Register (Selector sel, int ops, Object att)

This function is the same as the previous one, and the extra att parameters are stored as attachment in the returned Selectionkey, which is useful when you need to store some session state.

Boolean isregistered ()

Whether the channel is registered on one or more selector.



Selectablechannel also provides a way to get the corresponding Selectionkey:



Selectionkey keyfor (Selector sel)

Returns the selectionkey corresponding to the registration relationship of the Channe on selector. Returns null if there is no registered relationship.



Selector

Selector can monitor the IO status of multiple selectablechannel at the same time, which is the core of asynchronous IO.



Selector Open ()

A static method of selector that is used to create an instance.



In a selector, there are 3 sets of Selectionkey:

1. The key set represents all channel registered on this selector, which can be obtained by using the keys () method.

2. Selected-key set represents all channel monitored through the Select () method for IO operations, and this collection can be obtained by Selectedkeys ().

3. The Cancelled-key set represents the channel that has cancel the registration relationship, and in the next select () operation, these channel Selectionkey are removed from the key set and Cancelled-key set. This collection cannot be accessed directly.



The following is a description of the Select () Related method:



int Select ()

Monitor all registered channel, when a registered IO operation can be performed, the function returns, and the corresponding Selectionkey is added to the Selected-key set.

int Select (Long timeout)

You can set a select () operation that is timed out.

int Selectnow ()

Make an immediate return select () operation.

Selector Wakeup ()

Causes a Select () operation that has not yet returned returned immediately.



Selectionkey

Represents the registration relationship of selector and Selectablechannel.



The selector defines 4 static constants to represent 4 IO operations, which can be combined to form a bit mask.



int op_accept

There are new network connections that can be accept,serversocketchannel to support this asynchronous IO.

int Op_connect

Represents a connection that has been established (or is an error) and Socketchannel supports this asynchronous IO.

int Op_read

int Op_write

Represents a read and write operation.



The following are the main methods:



Object Attachment ()

The attachment,attachment that returns Selectionkey can be specified when registering channel.

Object Attach (Object OB)

Sets the attachment of the Selectionkey.

Selectablechannel Channel ()

Returns the channel corresponding to the Selectionkey.

Selector Selector ()

Returns the selector corresponding to the Selectionkey.

void Cancel ()

Cancel the registration relation of this selectionkey.

int Interestops ()

Returns the bit mask that represents IO operations that require selector monitoring.

Selectionkey interestops (int ops)

Set Interestops.

int Readyops ()

Returns a bit mask that represents the IO operation that can be performed on the corresponding channel.



Serversocketchannel

Support for asynchronous operations, corresponding to the Java.net.ServerSocket class, provides a TCP protocol IO interface to support op_accept operations.



ServerSocket socket ()

Returns the corresponding ServerSocket object.

Socketchannel Accept ()

Accepts a connection that returns the Socketchannel object that represents the connection.



Socketchannel

Support for asynchronous operations, corresponding to the Java.net.Socket class, provides a TCP protocol IO interface to support Op_connect,op_read and op_write operations. This class also implements the Bytechannel,scatteringbytechannel and Gatheringbytechannel interfaces.

Datagramchannel is similar to this class, and corresponds to the Java.net.DatagramSocket, which provides a UDP protocol IO interface.



Socket socket ()

Returns the corresponding socket object.

Boolean Connect (socketaddress remote)

Boolean Finishconnect ()

Connect () to perform a connection operation. If the current socketchannel is a blocking mode, this function will wait until the connection operation completes or the error occurs before returning. If the current socketchannel is a non-blocking mode, the function returns True if the connection can be created immediately, otherwise the function returns False, and the application needs to use the Finishconnect () method later to complete the join operation.



Pipe

Contains a read and a written channel (Pipe.sourcechannel and Pipe.sinkchannel), which channel can be used for communication in the process.



FileChannel

Used to read, write, map, lock and so on files. The class associated with the mapping operation has Filechannel.mapmode, and the class associated with the lock operation has filelock. It is worth noting that FileChannel does not support asynchronous operations.



Channels

This class provides a series of static methods to support interoperation between the stream class and the Channel class. These methods can wrap the channel class as a stream class, for example, wrap Readablebytechannel as InputStream or reader, or you can wrap the stream class as a channel class, for example, Package the OutputStream as Writablebytechannel.





Package Java.nio.charset

This package defines the charset and corresponding encoder and decoder. The UML class diagram below describes the relationship of the classes in this package and can interpret Charset,charsetdecoder and charsetencoder as an implementation of an abstract factory pattern:






Charset

Represents a character set and provides factory method to build the corresponding Charsetdecoder and Charsetencoder.



CharSet provides the following static methods:



SortedMap Availablecharsets ()

Returns all CharSet objects supported by the current system, using the name of CharSet as the key of the set.

Boolean issupported (String charsetname)

Determines whether the character set that corresponds to the name is supported by the current system.

Charset forname (String charsetname)

Returns the CharSet object that corresponds to the name.



The more important methods in CharSet are:



String name ()

Returns the canonical name of the character set.

Set aliases ()

Returns all aliases for this character set.

Charsetdecoder Newdecoder ()

Create a decoder that corresponds to this charset.

Charsetencoder Newencoder ()

Create a encoder that corresponds to this charset.



Charsetdecoder

The engine that decodes a byte stream encoded by some character set to Unicode character data.



The input of Charsetdecoder is Bytebuffer, the output is charbuffer. The following steps are generally performed when decode operations are performed:



1. Call the Reset () method of the Charsetdecoder. (not invoked on first use)

2. Call the Decode () method 0 through N, set the Endofinput argument to False, and tell decoder there is a possibility of new data being fed.

3. The last time the Decode () method is invoked, the Endofinput argument is set to true, telling decoder that all data has been sent.

4. Invokes the decoder flush () method. Let decoder have the opportunity to write some internal state to the output of the Charbuffer.



Charsetdecoder Reset ()

Resets the decoder and clears some of the internal states in the decoder.

Coderresult Decode (Bytebuffer in, Charbuffer out, Boolean endofinput)

Decode as many bytes as possible from the input of the Bytebuffer type and writes the result to the output of the Charbuffer type. According to the results of decode, It is possible to return 3 CoderResult:CoderResult.UNDERFLOW that no input can be decode;coderresult.overflow to indicate that the output is full, and that other coderresult indicate an error occurred in the decode process. Depending on the results returned, the application can take appropriate measures, such as increasing input, clearing output, and so on, and then calling the Decode () method again.

Coderresult Flush (Charbuffer out)

Some decoder will retain some internal state in the decode process, calling this method to give these decoder the opportunity to write these internal states to the charbuffer of the output. The call successfully returned Coderresult.underflow. If there is not enough space for the output, the function returns Coderresult.overflow, when the application should enlarge the space for the output charbuffer and then call the method again.

Charbuffer decode (Bytebuffer in)

A convenient way to decode the contents of Bytebuffer into a newly created charbuffer. The 4 steps mentioned above are included in this method and cannot be used with the first 3 functions.



There are two types of errors in the decode process: Malformed-input Coderresult indicates that the data in the input is incorrect, and Unmappable-character Coderresult indicates that there is data in the input that cannot be decoded into Unicode characters. How you handle errors in the decode process depends on the decoder settings. For both of these errors, decoder can be set by codingerroraction:

1. Ignoring errors

2. Report an error. (This causes an error to occur, the Decode () method returns a Coderresult that represents the error.) )

3. Replace the error, replacing the wrong part with the replacement string in decoder.



Codingerroraction malformedinputaction ()

Returns error handling for Malformed-input.

Charsetdecoder onmalformedinput (codingerroraction newaction)

Sets error handling for Malformed-input.

Codingerroraction unmappablecharacteraction ()

Returns error handling for Unmappable-character.

Charsetdecoder Onunmappablecharacter (codingerroraction newaction)

Sets error handling for Unmappable-character.

String replacement ()

Returns a decoder replacement string.

Charsetdecoder replacewith (String newreplacement)

Sets the replacement string for the decoder.



Charsetencoder

An engine that encodes Unicode character data into a byte stream for a specific character set. Its interface is similar to that of Charsetdecoder.



Coderresult

A class that describes the results of a encode/decode operation.



Coderesult contains two static members:



Coderresult OVERFLOW

Indicates that the output is full

Coderresult underflow

Indicates that no data is available for input.



Its main member functions are:



Boolean IsError ()

Boolean ismalformed ()

Boolean isunmappable ()

Boolean Isoverflow ()

Boolean Isunderflow ()

Used to determine the error described by the Coderresult.



int Length ()

Returns the length of the error, such as the byte length that cannot be converted to Unicode.

void ThrowException ()

Throws a exception corresponding to this coderresult.



Codingerroraction

A class that represents an error-handling method in Encoder/decoder. It can be viewed as an enum type. The following static properties are available:



Codingerroraction IGNORE

Ignore the error.

Codingerroraction REPLACE

Replaces the part with the error with a replacement string.

Codingerroraction

Report an error, for different functions, it is possible to return an error-related coderresult, or it may be thrown a charactercodingexception.





Reference documents

David Flanagan–java in a nutshell






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.