Java NIO3: Channels and file channels

Source: Internet
Author: User

What's the channel?

Channel type is the second major innovation of Java.nio. The channel is neither an extension nor an enhancement, but a new, excellent Java I/O example that provides a direct connection to the I/O service. channel is used to efficiently transfer data between a byte buffer and an entity located on the other side of the channel (typically a file or socket) .

Typically, a channel has a one-to-one relationship with the operating system's file descriptor (filedescriptor) and file handle (Filehandler). Although the channel is more generalized than the file descriptor, most of the channels that developers often use are connected to open file descriptors. The Channel class provides the abstraction required to maintain platform independence, or it still simulates the I/O performance of the modern operating system itself.

A channel is a way to access the I/O services of the operating system itself with minimal total overhead. The buffer is the endpoint within the channel used to send and receive data, such as:

Channel Basics

First, look at the basic channel interface, below is the full source of the Channel interface:

 Public InterfaceChannelextendscloseable {/*** Tells whether or not this channel is open. </p> * *@return<tt>true</tt> If, and only if, this channel is open*/     Public BooleanIsOpen (); /*** Closes this channel. * * <p> after a channel was closed, any further attempt to invoke I/O * operations upon it would cause a {@linkClosedchannelexception} to is * thrown.     * * <p> If This channel was already closed then invoking this method has no * effect.  * * <p> This method is invoked at any time. If some other thread have * already invoked it, however, then another invocation would block until * the first INVOC Ation is complete and after which it'll return without * effect. </p> * *@throwsIOException If An I/O error occurs*/     Public voidClose ()throwsIOException;}

Unlike buffers, the channel API is primarily specified by the interface. There are fundamental differences in channel implementations on different operating systems, so the channel API simply describes what can be done, so it is natural that the channel implementations often use the operating system's native code, which allows the developer to access the underlying I/O services in a controlled and portable manner.

It is possible to see from the underlying channel interface that there are only two common actions for all channels: checking whether a channel opens IsOpen () and closing an open channel close (), and everything else is the class that implements the channel interface and its sub-interfaces.

Other interfaces that are invisible from the channel interface are byte-oriented sub-interfaces:

including Writablebytechannel and Readablebytechannel. This also supports what we learned before: the channel can only operate on a byte buffer. The hierarchical interface indicates that the channels of other data types can also be extended from the channel interface. This is a good laser machine, but non-byte implementations are not possible because the operating system implements the underlying I/O interfaces in bytes.

Understanding Channels

Look at the basic interface:

 Public Interface extends Channel {    publicintthrows  IOException;}
 Public Interface Writablebytechannel     extends channel{    publicintthrows  IOException;}
 Public Interface Bytechannel     extends Readablebytechannel, writablebytechannel{}

The channels can be unidirectional or bidirectional. A channel class might implement the Readablebytechannel interface that defines the read () method, while another channel class might implement the Writablebytechannel interface to provide the write () method. The classes that implement either interface are one-way and can only transmit data in one direction. If a class implements both interfaces at the same time, it is bidirectional and can transmit data in two directions, just like the bytechannel above.

The channel can run in blocking (blocking) or non-blocking (nonblocking) mode, the non-blocking channel never sleeps the calling thread, the requested operation is either completed immediately, or a result is returned indicating that nothing has been done. only stream-oriented (stream-oriented) channels, such as sockets and pipes, can use nonblocking mode .

For example, non-blocking channel Socketchannel:

 Public Abstract class Socketchannel     extends Abstractselectablechannel     Implements Bytechannel, Scatteringbytechannel, gatheringbytechannel{...    }
 Public Abstract class Abstractselectablechannel     extends selectablechannel{...   }

As you can see, the socket channel class is derived from the Selectablechannel class, and classes derived from Selectablechannel can be used with selectors that support conditional selection (selectors). Combining non-blocking I/O and selectors allows the developer's program to take advantage of multiplexed I/O, and selectors and multiplexing will be described later in the article.

Understanding File Channels

The channel is the conduit that accesses the I/O service, and I/O can be divided into two broad categories: File I/O and stream I/O. Accordingly, there are two types of channels, which are file and socket (socket) channels. The file channel refers to the FileChannel, the socket channel has three, respectively is Socketchannel, Serversocketchannel and Datagramchannel.

Channels can be created in a variety of ways. The socket channel can have a factory method that directly creates the socket channel, but a FileChannel object is only passed in an open randomaccessfile, The FileInputStream or FileOutputStream object calls the Getchannel () method to get, and the developer cannot directly create a FileChannel.

File I/O is the most commonly used I/O, so this part first recognizes the file channel, and the next section shows you how to use the file channel height in code form. Use UML diagrams to represent the class hierarchy of file channels:

file channels are always blocked and therefore cannot be placed in nonblocking mode .

As mentioned earlier, the FileChannel object cannot be created directly, and an FileChannel instance can only be passed in an open file object (Randomaccessfile, FileInputStream or FileOutputStream) call the Getchannel () method to get, call Getchannel () The FileChannel method returns a FileChannel object that is connected to the same file and has the same access rights as the file object, and can then use the channel object to take advantage of the powerful FileChannel API.

FileChannel objects are thread-safe , and multiple processes can invoke methods concurrently on the same instance without causing any problems, but not all operations are multithreaded. Actions that affect the channel location or affect the file are single-threaded, and if one thread is already performing an operation that affects the channel location or file size, other threads that attempt one of these operations must wait, and the concurrency behavior is affected by the underlying operating system or file system.

Reading data using file channels

Having told so many theories, let's look at how to use the file channel, first reading the data from the file:

 public  static  void  Main (string[] args) throws   exception{file File  = new  file ("D:/files/readchannel.txt" ); FileInputStream fis  = new      FileInputStream (file);    FileChannel FC  = Fis.getchannel ();    Bytebuffer bb  = bytebuffer.allocate (35);    Fc.read (BB);    Bb.flip ();  while   (Bb.hasremaining ()) {System.out    . Print (( char  ) Bb.get ());    } bb.clear (); Fc.close ();}  

This is the simplest operation, before the file channel must be obtained through an open randomaccessfile, FileInputStream, FileOutputStream, So use fileinputstream here to get FileChannel. Then, as long as the content is read into the buffer using the Read method, and the buffer has data in it, you can read the data using the preceding operation for the buffer. The data inside the file is:

The data printed on the console are:

channel1! Channel2! channel3!

No problem.

Write data using a file channel

Read the data using file channels, and then look at using file channels to write data, almost:

 Public Static void throws exception{    new File ("D:/files/writechannel.txt");     New Randomaccessfile (file, "RW");     = Raf.getchannel ();     = Bytebuffer.allocate (ten);     = "Abcdefghij";    Bb.put (Str.getbytes ());    Bb.flip ();    Fc.write (BB);    Bb.clear ();    Fc.close ();}

Here used Randomaccessfile to get filechannel, and then operation is almost, write method writes Bytebuffer content into the file, pay attention to write before the Bytebuffer to flip.

Some people may find this method of continuous put is very inconvenient, but there is no way, it has been mentioned before: the channel can only use Bytebuffer.

Java NIO3: Channels and file channels

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.