Example of using Java NIO to share _java

Source: Internet
Author: User
Tags java se

Java NIO (New Input/output)------------is introduced into J2SE 1.4 in 2002. The goal of Java NIO is to improve the performance of I/O-intensive tasks on the Java platform. Ten years later, many Java developers still don't know how to make full use of NIO, and fewer people know that an updated input/output API (nio.2) has been introduced into Java SE 7. The biggest contribution of NIO and Nio.2 to the Java platform is to improve the performance of one of the core components of Java Application Development: input/output processing. Both of these packages are not very good, and they are not applicable to all scenarios. Java NiO and nio.2 can significantly reduce the time spent on some common I/O operations if they are used correctly. This is the super power of NiO and nio.2, and I'll show you 5 simple ways to use them in this article.

Change notification (because each event requires a listener)
Selector and asynchronous IO: improving multiplexing through selectors
Channel-Promise and reality
Memory mapping--good steel used on the blade
Character encoding and searching
Background of NiO

Why is an enhanced package that has been in existence for 10 years still a new Java I/O package? The reason is that for most Java programmers, basic I/O operations are capable. In daily work, most Java developers do not need to learn about NIO. Further, NiO is more than just a performance boost package. Instead, it is a collection of different functions related to Java I/O. NIO achieves performance improvement by making Java application Performance "closer to real", meaning that NiO and nio.2 APIs expose low-level system operations to the portal. The price of NIO is that it provides more powerful I/O control and requires more careful use and practice than basic I/O programming. Another feature of NIO is its focus on the expressiveness of applications, which we'll see in the exercises below.

Start learning about NIO and nio.2

There are many references to NiO-some of the links selected in resources. The Java 2 SDK Standard Edition (SE) documentation and Java SE 7 documentation are essential to learn about NiO and nio.2. To use the code in this article, you need to use JDK 7 or later.

For many developers, the first time they encounter NiO may be in the maintenance of the application: a functional application of a normal response to slow, so it is recommended to use NIO to improve response speed. NiO is superior when it comes to improving application performance, but the exact results depend on the underlying system. (Note that NIO is platform-dependent). If you are using NiO for the first time, you need to weigh it carefully. You will find that the ability of NIO to improve performance depends not only on the OS, but also on the JVM you use, the virtual context of the host, the nature of the bulk storage, and even the data. Therefore, performance measurement of the work is more difficult to do. Especially when you have a mobile deployment environment in your system, you need to pay special attention.

Having learned the above, we have no worries, and now we're going to experience the 5 important features of NiO and nio.2.

1. Change notification (because each event requires a listener)

The common concern of developers interested in NiO and Nio.2 is the performance of Java applications. In my experience, the file change notifier in Nio.2 is one of the most interesting (underrated) features of the new input/output API.

Many enterprise applications need to do some special processing in the following situations:

When a file is uploaded to an FTP folder
When the definition in a configuration is modified
When a draft document is uploaded
When other file system events occur
These are examples of change notifications or change responses. In earlier versions of Java (and other languages), polling (polling) was the best way to detect these change events. Polling is a special kind of infinite loop: Check the file system or other objects and compare it to the previous state, and if not, continue checking after approximately hundreds of milliseconds or 10 seconds of interval. It's been going on indefinitely.

Nio.2 provides a better way to make change detection. Listing 1 is a simple example.

Listing 1. Notification mechanism for change in nio.2

Copy Code code as follows:

Import java.nio.file.attribute.*;
importjava.io.*;
importjava.util.*;
Importjava.nio.file.Path;
Importjava.nio.file.Paths;
Importjava.nio.file.StandardWatchEventKinds;
Importjava.nio.file.WatchEvent;
Importjava.nio.file.WatchKey;
Importjava.nio.file.WatchService;
Importjava.util.List;

publicclasswatcher{
Publicstaticvoidmain (String[]args) {
Paththis_dir=paths.get (".");
System.out.println ("Nowwatchingthecurrentdirectory ...");

try{
Watchservicewatcher=this_dir.getfilesystem (). Newwatchservice ();
This_dir.register (watcher,standardwatcheventkinds.entry_create);

Watchkeywatckkey=watcher.take ();

List<watchevent<<64;>>events=watckkey.pollevents ();
for (watcheventevent:events) {
System.out.println ("Someonejustcreatedthefile '" +event.context (). toString () + "'.");

}

}catch (Exceptione) {
System.out.println ("Error:" +e.tostring ());
}
}
}

Compile the code and execute it on the command line. In the same directory, create a new file, such as running Touchexample or copywatcher.classexample commands. You will see the following change notification message:

Someonejustcreatethefiel ' example1′.


This simple example shows how to start using the Javanio feature. It also introduces the Nio.2 Watcher class, which is more straightforward and easy to use than the original I/O polling scenario.

Note spelling errors

When you copy code from this article, pay attention to spelling mistakes. For example, the Standardwatcheventkinds object of the list 1 is in the form of a complex number. It's spelled wrong even in Java.net's documents.

Small Tips

The notification mechanism in NIO is simpler to use than the old polling method, which can induce you to ignore detailed analysis of specific requirements. When you first use a listener, you need to think carefully about the semantics of the concepts you use. For example, knowing when a change will end is more important than knowing when it starts. This kind of analysis needs to be very careful, especially in a common scenario like moving an FTP folder. NiO is a very powerful package, but at the same time it will have some subtle "traps" that can bring trouble to those who are unfamiliar with it.

2. Selector and asynchronous IO: Improve multiplexing by selector

New NIO Beginners generally associate it with "non-blocking input/Output". NiO is not just non-blocking I/O, but it is not entirely wrong: Java's basic I/O is blocking i/o--means it waits until the operation completes-however, non-blocking or asynchronous I/O is one of the most common features of NIO, not all of NIO.

The non-blocking I/O of NiO is event-driven and is demonstrated in the file system listener example in Listing 1. This means defining a selector (callback or listener) for an I/O channel, and then the program can continue to run. When an event occurs on this selector-for example, when a line of input is received-the selector "wakes up" and executes. All of this is done through a single thread, which differs significantly from Java's standard I/O.

Listing 2 shows a multiport network program implemented using the NIO selector, Echo-er, which modifies a small program that Gregtravis created in 2003 (a list of reference resources). The Unix and Unix-like systems have already implemented efficient selectors early on, which is a good reference model for the high performance programming model of the Java network.

Listing 2. NiO Selector

Copy Code code as follows:

importjava.io.*;
importjava.net.*;
importjava.nio.*;
importjava.nio.channels.*;
importjava.util.*;

Publicclassmultiportecho
{
Privateintports[];
Privatebytebufferechobuffer=bytebuffer.allocate (1024);

Publicmultiportecho (intports[]) throwsioexception{
This.ports=ports;

Configure_selector ();
}

Privatevoidconfigure_selector () throwsioexception{
Createanewselector
Selectorselector=selector.open ();

Openalisteneroneachport,andregistereachone
Withtheselector
for (Inti=0;i<ports.length;++i) {
Serversocketchannelssc=serversocketchannel.open ();
Ssc.configureblocking (FALSE);
Serversocketss=ssc.socket ();
Inetsocketaddressaddress=newinetsocketaddress (Ports[i]);
Ss.bind (address);

Selectionkeykey=ssc.register (selector,selectionkey.op_accept);

System.out.println ("Goingtolistenon" +ports[i]);
}

while (true) {
Intnum=selector.select ();

Setselectedkeys=selector.selectedkeys ();
Iteratorit=selectedkeys.iterator ();

while (It.hasnext ()) {
selectionkeykey= (Selectionkey) it.next ();

if ((Key.readyops () &selectionkey.op_accept)
==selectionkey.op_accept) {
Acceptthenewconnection
Serversocketchannelssc= (Serversocketchannel) Key.channel ();
Socketchannelsc=ssc.accept ();
Sc.configureblocking (FALSE);

Addthenewconnectiontotheselector
Selectionkeynewkey=sc.register (Selector,selectionkey.op_read);
It.remove ();

System.out.println ("Gotconnectionfrom" +SC);
}elseif ((Key.readyops () &selectionkey.op_read)
==selectionkey.op_read) {
Readthedata
Socketchannelsc= (Socketchannel) Key.channel ();

Echodata
Intbytesechoed=0;
while (true) {
Echobuffer.clear ();

Intnumber_of_bytes=sc.read (Echobuffer);

if (number_of_bytes<=0) {
Break
}

Echobuffer.flip ();

Sc.write (Echobuffer);
Bytesechoed+=number_of_bytes;
}

System.out.println ("echoed" +bytesechoed+ "from" +SC);

It.remove ();
}

}
}
}

Staticpublicvoidmain (stringargs[]) throwsexception{
if (args.length<=0) {
System.err.println ("Usage:javamultiportechoport[portport ...]");
System.exit (1);
}

Intports[]=newint[args.length];

for (Inti=0;i<args.length;++i) {
Ports[i]=integer.parseint (Args[i]);
}

Newmultiportecho (ports);
}
}

Compile the code, and then start it by using a command similar to javaMultiPortEcho80058006. Once the program runs successfully, start a simple telnet or other terminal emulator to connect the 8005 and 8006 interfaces. You will see that the program echoes all the characters it receives-and it is implemented through a Java thread.

3. Channel: Commitment and reality

In NiO, a channel (channel) can represent any object that can be read or written. Its role is to provide abstraction for files and sets of interfaces. The NIO channel supports a consistent set of methods so that coding does not require special attention to different objects, whether it is standard output, or a network connection or a channel in use. This feature of the channel is inherited from the Java basic I/O stream (stream). Flow (stream) provides a blocking IO, and a channel supports asynchronous I/O.

NIO is often recommended for its high performance, but more precisely because it responds quickly. In some scenarios nio can be worse than the basic JAVAI/O performance. For example, for simple sequential reads and writes of a small file, the simple flow of performance may be two to three times times faster than the corresponding object-oriented channel based coding. At the same time, non-multiplexing (Non-multiplex) channels--that is, a separate channel for each thread--are much slower than multiple channels registering their selectors in the same thread.

When you consider using a stream or channel, try asking yourself the following questions:

How many I/O objects do you need to read and write?
Do the different I/O objects have a direct order, or do they all need to happen at the same time?
Does your I/O object need to last for a short time or does it exist throughout the declaration cycle of your process?
Is your I/O suitable for single line Chengri processing or in several different lines Chengri?
Do network traffic and local I/O look the same, or do they have different patterns?
Such an analysis is a best practice for deciding whether to use a stream or a channel. Remember: NiO and nio.2 are not an alternative to basic I/O, but a complement to it.

4. Memory mapping--good steel used in the blade

The most notable performance improvement in NIO is memory mapping (memorymapping). Memory mapping is a system-level service that treats a section of a file used in a program as memory.

Memory mappings have many potential effects, much more than I offer here. At a higher level, it enables the performance of the I/O of file access to the speed of memory access. The speed of memory access is often several orders of magnitude faster than file access. Listing 3 is a simple example of a NIO memory map.

Listing 3. Memory mapping in NIO

Copy code code as follows:

Importjava.io.RandomAccessFile;
Importjava.nio.MappedByteBuffer;
Importjava.nio.channels.FileChannel;

publicclassmem_map_example{
privatestaticintmem_map_size=20*1024*1024;
Privatestaticstringfn= "Example_memory_mapped_file.txt";

Publicstaticvoidmain (String[]args) throwsexception{
Randomaccessfilememorymappedfile=newrandomaccessfile (FN, "RW");

Mappingafileintomemory
Mappedbytebufferout=memorymappedfile.getchannel (). Map (filechannel.mapmode.read_write,0,mem_map_size);

Writingintomemorymappedfile
for (inti=0;i<mem_map_size;i++) {
Out.put ((byte) ' A ');
}
System.out.println ("File" "+fn+" "Isnow" +integer.tostring (mem_map_size) + "bytesfull.");

Readfrommemory-mappedfile.
for (inti=0;i<30;i++) {
System.out.print ((char) out.get (i));
}
System.out.println ("\nreadingfrommemory-mappedfile '" +fn+ "' Iscomplete.");
}
}

In Listing 3, this simple example creates a 20M file Example_memory_mapped_file.txt and populates it with character a, and then reads the first 30 bytes. In practical applications, memory mapping is not only good at improving the original I/O speed, it also allows multiple different reader and writer to handle the same file image simultaneously. This technology is powerful but also dangerous, but if used correctly, it can increase your IO speed by several times. As we all know, the trading operations on Wall Street have used memory-mapping techniques in order to gain a second or even a millisecond advantage.

5. Character encoding and searching

The last feature of NiO that I'm going to explain in this article is charset, a package that converts different character encodings. Prior to NIO, Java implemented most of the same functionality with the GetByte method built in. CharSet is very popular because it is more flexible than getbytes and can be implemented at a lower level so that better performance can be achieved. This is more valuable for searching for non-English languages that are sensitive to coding, sequencing, and other language features.

Listing 4 shows an example of converting a Unicode character in Java into a Latin-1

Listing 4. The characters in NiO

Copy Code code as follows:

Stringsome_string= "Thisisastringthatjavanativelystoresasunicode."
Charsetlatin1_charset=charset.forname ("iso-8859-1");
Charsetencodelatin1_encoder=charset.newencoder ();
Bytebufferlatin1_bbuf=latin1_encoder.encode (Charbuffer.wrap (some_string));

Note that charset and channels are designed to be put together for use so that the program can work properly when it is working with the Save mappings, asynchronous I/O, and coded transformations.

Summary: Of course there's more to know

The purpose of this article is to familiarize Java developers with some of the most important (and most useful) features of NiO and nio.2. You can build on some of these examples to understand some of the other ways of NiO; For example, the knowledge you have learned about channels can help you understand the processing of the symbolic links in the file system in the path of NIO. You can also refer to the list of resources I have given later, which gives some in-depth documentation of the new Java I/OAPI.

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.