加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

An NIO.2 primer--reference

发布时间:2020-12-14 06:18:29 所属栏目:Java 来源:网络整理
导读:Part 1: The asynchronous channel APIs The More New I/O APIs for the Java? Platform (NIO.2) is one of the major new functional areas in Java 7,adding asynchronous channel functionality and a new file system API to the language. Developers w

Part 1: The asynchronous channel APIs

The More New I/O APIs for the Java? Platform (NIO.2) is one of the major new functional areas in Java 7,adding asynchronous channel functionality and a new file system API to the language. Developers will gain support for platform-independent file operations,asynchronous operations,and multicast socket channels. Part 1 of this two-part article focuses on the asynchronous channel APIs in NIO.2,and??covers the new file system functionality.

An?asynchronous channel?represents a connection that supports nonblocking operations,such as connecting,reading,and writing,and provides mechanisms for controlling the operations after they've been initiated. The More New I/O APIs for the Java Platform (NIO.2) in Java 7 enhance the New I/O APIs (NIO) introduced in Java 1.4 by adding four asynchronous channels to the?java.nio.channels?package:

    AsynchronousSocketChannel
  • AsynchronousServerSocketChannel
  • AsynchronousFileChannel
  • AsynchronousDatagramChannel

These classes are similar in style to the NIO channel APIs. They share the same method and argument structures,and most operations available to the NIO channel classes are also available in the new asynchronous versions. The main difference is that the new channels enable some operations to be executed asynchronously.

The asynchronous channel APIs provide two mechanisms for monitoring and controlling the initiated asynchronous operations. The first is by returning a?java.util.concurrent.Future?object,which models a pending operation and can be used to query its state and obtain the result. The second is by passing to the operation an object of a new class,?java.nio.channels.CompletionHandler,which defines handler methods that are executed after the operation has completed. Each asynchronous channel class defines duplicate API methods for each operation so that either mechanism can be used.

This article,the first in a??on NIO.2,introduces each of the channels and provides some simple examples to demonstrate their use. The examples are available in a runnable state (see?),and you can try them out on the Java 7 beta releases available from Oracle and IBM? (both still under development at the time of this writing; see?). In?,you'll learn about the NIO.2 file system API.

To start,we'll look at the?AsynchronousServerSocketChannel?and?AsynchronousSocketChannel?classes. Our first example demonstrates how a simple client/server can be implemented using these new classes. First we'll set up the server.

An?AsychronousServerSocketChannel?can be opened and bound to an address similarly to a?ServerSocketChannel:

The?bind()?method takes a socket address as its argument. A convenient way to find a free port is to pass in a?null?address,which automatically binds the socket to the local host address and uses a free?ephemeral?port.

Next,we can tell the channel to accept a connection:

This is the first difference from NIO. The accept call always returns immediately,and — unlike?ServerSocketChannel.accept(),which returns a?SocketChannel?— it returns a?Future?object that can be used to retrieve an?AsynchronousSocketChannelat a later time. The generic type of the?Future?object is the result of the actual operation. For example,a read or write returns aFuture?because the operation returns the number of bytes read or written.

Using the?Future?object,the current thread can block to wait for the result:

Here it blocks with a timeout of 10 seconds:

Or it can poll the current state of the operation,and also cancel the operation:

The?cancel()?method takes a boolean flag to indicate whether the thread performing the accept can be interrupted. This is a useful enhancement; in previous Java releases,blocking I/O operations like this could only be aborted by closing the socket.

Next,we can set up the client by opening and connecting a?AsynchronousSocketChannel?to the server:

Once the client is connected to the server,reads and writes can be performed via the channels using byte buffers,as shown in Listing 1:

// read a message from the client
worker.read(readBuffer).get(10,TimeUnit.SECONDS);
System.out.println("Message: " + new String(readBuffer.array()));

Scattering reads and writes,which take an array of byte buffers,are also supported asynchronously.

The APIs of the new asynchronous channels completely abstract away from the underlying sockets: there's no way to obtain the socket directly,whereas previously you could call?socket()?on,for example,a?SocketChannel. Two new methods —?getOption?and?setOption?— have been introduced for querying and setting socket options in the asynchronous network channels. For example,the receive buffer size can be retrieved by?channel.getOption(StandardSocketOption.SO_RCVBUF)?instead of?channel.socket().getReceiveBufferSize();.

The alternative mechanism to using?Future?objects is to register a callback to the asynchronous operation. The?CompletionHandler?interface has two methods:

    void completed(V result,A attachment)?executes if a task completes with a result of type?V.
  • void failed(Throwable e,A attachment)?executes if the task fails to complete due to?Throwable e.

The attachment parameter of both methods is an object that is passed in to the asynchronous operation. It can be used to track which operation finished if the same completion-handler object is used for multiple operations.

Let's look at an example using the?AsynchronousFileChannel?class. We can create a new channel by passing in a?java.nio.file.Path?object to the static?open()?method:

open?commands for?FileChannel

The format of the open commands for asynchronous channels has been backported to the?FileChannelclass. Under NIO,a?FileChannel?is obtained by calling?getChannel()?on a?FileInputStream,FileOutputStream,or?RandomAccessFile. With NIO.2,a?FileChannel?can be created directly using anopen()?method,as in the examples shown here.

Path?is a new class in Java 7 that we look at in more detail in?. We use thePaths.get(String)?utility method to create a?Path?from a?String?representing the filename.

By default,the file is opened for reading. The?open()?method can take additional options to specify how the file is opened. For example,this call opens a file for reading and writing,creates it if necessary,and tries to delete it when the channel is closed or when the JVM terminates:

An alternative?open()?method provides finer control over the channel,allowing file attributes to be set.

Next,we want to write to the file and then,once the write has completed,execute something. We first construct a?CompletionHandler?that encapsulates the "something" as shown in Listing 2:

handler = new CompletionHandler() { @Override public void completed(Integer result,Object attachment) { System.out.println(attachment + " completed with " + result + " bytes written"); } @Override public void failed(Throwable e,Object attachment) { System.err.println(attachment + " failed with:"); e.printStackTrace(); } };

Now we can perform the write:

The?write()?method takes:

    A?ByteBuffer?containing the contents to write
  • An absolute position in the file
  • An attachment object that is passed on to the completion handler methods
  • A completion handler

Operations must give an absolute position in the file to read to or write from. It doesn't make sense for the file to have an internal position marker and for reads/writes to occur from there,because the operations can be initiated before previous ones are completed and the order they occur in is not guaranteed. For the same reason,there are no methods in the?AsynchronousFileChannel?API that set or query the position,as there are in?FileChannel.

In addition to the read and write methods,an asynchronous lock method is also supported,so that a file can be locked for exclusive access without having to block in the current thread (or poll using?tryLock) if another thread currently holds the lock.

Each asynchronous channel constructed belongs to a?channel group?that shares a pool of Java threads,which are used for handling the completion of initiated asynchronous I/O operations. This might sound like a bit of a cheat,because you could implement most of the asynchronous functionality yourself in Java threads to get the same behaviour,and you'd hope that NIO.2 could be implemented purely using the operating system's asynchronous I/O capabilities for better performance. However,in some cases,it's necessary to use Java threads: for instance,the completion-handler methods are guaranteed to be executed on threads from the pool.

By default,channels constructed with the?open()?methods belong to a global channel group that can be configured using the following system variables:

    java.nio.channels.DefaultThreadPoolthreadFactory,which defines a?java.util.concurrent.ThreadFactory?to use instead of the default one
  • java.nio.channels.DefaultThreadPool.initialSize,which specifies the thread pool's initial size

Three utility methods in?java.nio.channels.AsynchronousChannelGroup?provide a way to create new channel groups:

    withCachedThreadPool()
  • withFixedThreadPool()
  • withThreadPool()

These methods take either the definition of the thread pool,given as a?java.util.concurrent.ExecutorService,or ajava.util.concurrent.ThreadFactory. For example,the following call creates a new channel group that has a fixed pool of 10 threads,each of which is constructed with the default thread factory from the?Executors?class:

The three asynchronous network channels have an alternative version of the?open()?method that takes a given channel group to use instead of the default one. For example,this call tells?channel?to use the?tenThreadGroup?instead of the default channel group to obtain threads when required by the asynchronous operations:

Defining your own channel group allows finer control over the threads used to service the operations and also provides mechanisms for shutting down the threads and awaiting termination. Listing 3 shows an example:

The?AsynchronousFileChannel?differs from the other channels in that,in order to use a custom thread pool,the?open()?method takes anExecutorService?instead of an?AsynchronousChannelGroup.

The final new channel is the?AsynchronousDatagramChannel. It's similar to the?AsynchronousSocketChannel?but worth mentioning separately because the NIO.2 API adds support for multicasting to the channel level,whereas in NIO it is only supported at the level of theMulticastDatagramSocket. The functionality is also available in?java.nio.channels.DatagramChannel?from Java 7.

An?AsynchronousDatagramChannel?to use as a server can be constructed as follows:

Next,we set up a client to receive datagrams broadcast to a multicast address. First,we must choose an address in the multicast range (from 224.0.0.0 to and including 239.255.255.255),and also a port that all clients can bind to:

We also require a reference to which network interface to use:

Now,we open the datagram channel and set up the options for multicasting,as shown in Listing 4:

The client can join the multicast group in the following way:

The?java.util.channels.MembershipKey?is a new class that provides control over the group membership. Using the key you can drop the membership,block and unblock datagrams from certain addresses,and return information about the group and channel.

The server can then send a datagram to the address and port for the client to receive,as shown in Listing 5:

// receive message
final ByteBuffer buffer = ByteBuffer.allocate(100);
client.receive(buffer,null,new CompletionHandler<SocketAddress,Object>() {
@Override
public void completed(SocketAddress address,Object attachment) {
System.out.println("Message from " + address + ": " +
new String(buffer.array()));
}

@Override
public void failed(Throwable e,Object attachment) {
    System.err.println("Error receiving datagram");
    e.printStackTrace();
}

});

Multiple clients can also be created on the same port and joined to the multicast group to receive the datagrams sent from the server.

NIO.2's asynchronous channel APIs provide a convenient and standard way of performing asynchronous operations platform-independently. They allow application developers to write programs that use asynchronous I/O in a clear manner,without having to define their own Java threads and,in addition,may give performance improvements by using the asynchronous support on the underlying OS. As with many Java APIs,the amount that the API can exploit an OS's native asynchronous capabilities will depend on the support for that platform.

Part 2: The file system APIs

This article completes our two-part introduction to More New I/O APIs for Java (NIO.2) in Java 7. Like the asynchronous channel APIs explored in?,NIO.2's file system APIs fill some significant gaps in the way previous Java versions handle I/O. According to the NIO.2 Java specification request (JSR 203):

The Java platform has long needed a filesystem interface better than the?java.io.File?class. That class does not handle filenames in a way that works consistently across platforms,it does not support efficient file-attribute access,it does not allow sophisticated applications to take advantage of filesystem-specific features (for example,symbolic links) when available,and many of its methods simply return false on error instead of throwing an informative exception.

Coming to the rescue are three new file system packages in the Java 7 beta:

    java.nio.file
  • java.nio.file.attribute
  • java.nio.file.spi

This article focuses on the most useful classes in these packages:

    java.nio.file.Files?and?java.nio.file.FileVisitor?allow you to walk through file systems,querying files or directories up to a certain depth and executing user-implemented callback methods for each one found.
  • java.nio.file.Path?and?java.nio.file.WatchService?allow you to register to "watch" a specific directory. An application watching directories receives notification if files in those directories are created,modified,or deleted.
  • java.nio.attribute.*AttributeView?allow you to view file and directory attributes that were previously hidden from Java users. These attributes include file owner and group permissions,access-control lists (ACLs),and extended file attributes.

We'll provide examples that show how to use these classes. The examples are available in a runnable state (see?),and you can try them out on the Java 7 betas available from IBM? and Oracle (both still under development at the time of this writing; see?).

Our first example demonstrates the new?FileVisitor?API.

Imagine a scenario in which you want to traverse a directory tree recursively,stopping at each file and directory under that tree and having your own callback methods invoked for each entry found. In previous Java versions,this would have been a painful process involving recursively listing directories,inspecting their entries,and invoking the callbacks yourself. In Java 7,this is all provided via the?FileVisitor?API,and using it couldn't be simpler.

The first step is to implement your own?FileVisitor?class. This class contains the callback methods that the file-visitor engine will invoke as it traverses the file system. The?FileVisitor?interface consists of five methods,listed here in the typical order they would be called during traversal (T?here stands for either?java.nio.file.Path?or a superclass):

    FileVisitResult preVisitDirectory(T?dir)?is called before the entries in that directory are visited. It returns one of theFileVisitResult's enum values to tell the file visitor API what to do next.
  • FileVisitResult preVisitDirectoryFailed(T?dir,IOException exception)?is called when a directory could not be visited for some reason. The exception that caused the visit to fail is specified in the second parameter.
  • FileVisitResult visitFile(T?file,BasicFileAttributes attribs)?is called when a file in the current directory is being visited. The attributes for this file are passed into the second parameter. (You'll learn more about file attributes in this article's??section.)
  • FileVisitResult visitFileFailed(T?file,IOException exception)?is called when the visit to a file has failed. The second parameter specifies the exception that caused the visit to fail.
  • FileVisitResult postVisitDirectory(T?dir,IOException exception)?is called after the visit to a directory and all its subdirectories has completed. The exception parameter is null when the directory visit has been successful,or it contains the exception that caused the directory visit to end prematurely.

To help developers save time,NIO.2 has kindly provided an implementation of the?FileVisitor?interface:?java.nio.file.SimpleFileVisitor. This class is as basic as it gets: for the *Failed()?methods,it just rethrows the exception,and for the other methods it continues without doing anything at all! What's useful about this class is that you can use anonymous classes to override only the methods you want; the rest of the methods are implemented by default.

Listing 1 shows how we create an example?FileVisitor?instance:

FileVisitor?implementation
myFileVisitor = new SimpleFileVisitor() {
@Override
public FileVisitResult preVisitDirectory(Path dir) { 
   System.out.println("I'm about to visit the "+dir+" directory"); 
   return FileVisitResult.CONTINUE;
}

@Override 
public FileVisitResult visitFile(Path file,BasicFileAttributes attribs) {

   System.out.println("I'm visiting file "+file+" which has size " +attribs.size());
   return FileVisitResult.CONTINUE;
}

};

The?FileVisitor?implementation in??should print a message for each directory and file it visits and also give the size of the files from their?BasicFileAttributes.

Next we want to create a?Path?from which to start our file visiting. This is done using the?java.nio.Paths?class:

We can use either of two methods on the?java.nio.Files?class to start the tree traversal:

    public static void walkFileTree(Path head,FileVisitor fileVisitor)?walks the file tree under the head directory,invoking the callback methods implemented in?fileVisitor?as it goes.
  • public static void walkFileTree(Path head,Set options,int depth,FileVisitor fileVisitor)?is similar to the preceding method but gives you two additional parameters to specify visit options and how many directories deep into the file tree the traversal should go.

We'll use the simpler version of the?walkFileTree()?method to start the process of walking the file tree:

Suppose the directory structure looks like this:

Listing 2 shows the output from this example:

FileVisitor?output

As you can see,the file traversal is depth first but not necessarily in any alphabetical order within a directory. Our callback methods were invoked as expected,and we can see that all the files in the tree have been listed and all the directories have been visited.

In only about 15 lines,we've created a file visitor that will walk any file tree you give it and inspect the files contained therein. This example is basic,but the callbacks can be implemented to be as complex as you want.

This second example covers the exciting world of the new?WatchService?API and its associated classes.

The scenario for this example is simple: You'd like to track whether any files or directories in a particular directory (or directories) are being created,or deleted. You might use this information to update a file listing in a GUI display or perhaps to detect the modification of configuration files that could then be reloaded. In previous Java versions,you must implement an agent running in a separate thread that keeps track of all the contents of the directories you wish to watch,constantly polling the file system to see if anything relevant has happened. In Java 7,the?WatchService?API provides the ability to watch directories. It removes all the complexity of writing your own file system poller and,where possible,is based upon existing native system APIs for better performance.

The first step is to create a?WatchService?instance via the?java.nio.file.FileSystems?class. We won't go into the details of file systems in this article,so just know that in most cases you'll want to get the default file system and then invoke its?newWatchService()?method:

Now that we have our watch service instance,we want to register a path to watch. We create a?Path?object for the directory we wish to watch in a slightly different way from the file visitor example,so that we can use its?File?instance again later:

The?Path?class implements the?java.nio.file.Watchable?interface,and that interface defines the?register()?method we'll be using in this example.?WatchKey register(WatchService watchService,WatchEvent.Kind... events)?registers the?Path?this method is called on with the specified?watchService?for the specific events given. Events trigger a notification only if they are specified in the register call.

For the default?WatchService?implementation,the?java.nio.file.StandardWatchEventKind?class defines three static implementations ofwatchEvent.Kind?that can be used in the?register()?calls:

    StandardWatchEventKind.ENTRY_CREATE?indicates that a file or directory has been created within the registered?Path. An?ENTRY_CREATEevent is also triggered when a file is renamed or moved into this directory.
  • StandardWatchEventKind.ENTRY_MODIFY?indicates that a file or directory in the registered?Path?has been modified. Exactly which events constitute a modification is somewhat platform-specific,but suffice it to say that actually modifying the contents of a file always triggers a modify event. On some platforms,changing attributes of files can also trigger this event.
  • StandardWatchEventKind.ENTRY_DELETE?indicates that a file or directory has been deleted from the registered?Path. An?ENTRY_DELETE?event is also triggered when a file is renamed or moved out of this directory.

For our example,let's watch the?ENTRY_CREATE?and?ENTRY_MODIFY?events,but not?ENTRY_DELETE:

Our?Path?is now registered to be watched,and the?WatchService?will work away silently in the background,watching that directory intently. The same?WatchService?instance can watch multiple directories by using the same?Path?creation and?register()?calls we've shown above.

The observant among you may have spotted that the?register()?method call returns a class we haven't come across before:?WatchKey. This class represents your registration with the?WatchService. Whether you hang onto this reference or not is up to you,because the?WatchServicereturns the relevant?WatchKey?to you when an event is triggered. However,do note that there are no method calls to find out?which?directory theWatchKey?was registered with,so if you're watching multiple directories you may wish to track which?WatchKeys go with which?Paths. When you're done with a particular?WatchKey?and the events it's registered for,you can cancel its registration with the?WatchService?simply by calling its?cancel()?method.

Now that our?Path?is registered,we can check in with the?WatchService?at our convenience to see if any of the events we were interested in has occurred.?WatchService?provides three methods for checking if anything exciting has happened:

    WatchKey poll()?returns the next?WatchKey?that has had some of its events occur,or?null?if no registered events have happened.
  • WatchKey poll(long timeout,TimeUnit unit)?takes a timeout and time units (java.util.concurrent.TimeUnit). If an event occurs during the specified time period,this method exits,returning the relevant?WatchKey. If there are no?WatchKeys?to return by the end of the timeout,this method returns?null.
  • WatchKey take()?is similar to the preceding methods,except it will wait indefinitely until a?WatchKey?is available to return.

Once a?WatchKey?has been returned by one of these three methods,it will not be returned by a further?poll()?or?take()?call until its?reset()method is invoked,even if events it is registered for occur. Once a?WatchKey?is returned by the?WatchService,you can inspect its events that have been triggered by calling the?WatchKey's?pollEvents()?method,which returns a List of?WatchEvents.

To illustrate,the simple example in Listing 3 continues from the?WatchKey?we registered earlier:

pollEvents()
// Now call take() and see if the event has been registered
WatchKey watchKey = watchService.take();
for (WatchEvent<?> event : watchKey.pollEvents()) {
System.out.println(
"An event was found after file creation of kind " + event.kind()

  • ". The event occurred on file " + event.context() + ".");
    }

When executed,the code in??prints:

As you can see,we got the?ENTRY_CREATE?event for the newly created?tempFile?as expected,but we also got another event. On some operating systems,a file creation or deletion can sometimes also produce an?ENTRY_MODIFY?event. If we had not registered to receive modification events,then we would have only gotten the?ENTRY_CREATE?event,whatever the OS.

Extended sample code (demonstrating file modification and deletion for the registered?WatchKey?in this section's example) is included in the sample code?.

Our third and final example covers the new APIs for getting and setting file attributes using the classes under the?java.nio.file.attributepackage.

The new APIs offer access to more file attributes than you can imagine. In previous Java releases,you can get only a basic set of file attributes (size,modification time,whether the file is hidden,and whether it is a file or directory). To get or modify any further file attributes,you must implement this yourself in native code specific to the platforms you want to run on — not exactly easy. Brilliantly,Java 7 should allow you to read and,modify an extended set of attributes in a simple way via the?java.nio.file.attribute?classes,completely abstracting away the platform-specific nature of these operations.

Seven?attribute views?are available in the new APIs,some of which are specific to the operating system. These "view" classes allow you to get and set whichever attributes they are associated with,and each one has a counterpart attribute class that contains the actual attribute information. Let's take a look at them in turn.

AclFileAttributeView?and?AclEntry

AclFileAttributeView?allows you to get and set the ACL and file-owner attributes of a particular file. Its?getAcl()?method returns a?List?ofAclEntry?objects,one for each permission set on the file. Its?setAcl(List)?method allows you to modify that access list. This attribute view is only available for Microsoft? Windows? systems.

BasicFileAttributeView?and?BasicFileAttributes

This view class allows you to get a set of — no surprise — basic file attributes,building on those available in previous Java versions. ItsreadAttributes()?method returns a?BasicFileAttributes?instance containing details of last modified time,last access time,creation time,size,and type of file (regular file,directory,symbolic link,or other). This attribute view is available on all platforms.

Let's look at an example of this view. To get a file attribute view for a particular file we start,as always,by creating a?Path?object for the file we're interested in:

To get the file attribute view we want,we'll use the?getFileAttributeView(Class viewClass)?method on?Path. To get theBasicFileAttributeView?for?attribPath,we simply call:

As described earlier,to get the?BasicFileAttributes?from?BasicFileAttributeView,we just call its?readAttributes()?method:

And that's it. Now you have all of the basic file attributes for that file to do whatever you wish with. For the?BasicFileAttributes,only the creation,last-modified,and last-access times can be altered (because it wouldn't make sense to change the size or type of file). To change these,we can use the?java.nio.file.attribute.FileTime?class to create a new time and then call the?setTimes()?method onBasicFileAttributeView. For example,we could move the last-modified time for our file a minute further into the future:

The two?nulls indicate that we do not want to change the last access time or creation time for this file. If you check the basic attributes again,in the same way we did earlier,you should see that the last modified time has been altered but the creation time and last access time have remained the same.

DosFileAttributeView?and?DosFileAttributes

This view class allows you to get attributes specific to DOS. (As you might guess,this view is for Windows systems only.) Its?readAttributes()method returns a?DosFileAttributes?instance containing details of whether the file in question is read-only,hidden,a system file,and an archive. The view also has?set*(boolean)?methods for each of these properties.

FileOwnerAttributeView?and?UserPrincipal

This view class allows you to get and set the owner of a particular file. Its?getOwner()?method returns a?UserPrincipal?(also in thejava.nio.file.attribute?package),which in turn has a?getName()?method returning a?String?containing the owner's name. The view also provides a?setOwner(UserPrincipal)?method allowing you to change a file's owner. This view is available on all platforms.

FileStoreSpaceAttributeView?and?FileStoreSpaceAttributes

This catchily named class allows you to get information about a particular file store. Its?readAttributes()?method returns aFileStoreSpaceAttributes?instance containing details of the total space,the unallocated space,and the usable space on the file store. This view is available on all platforms.

PosixFileAttributeView?and?PosixFileAttributes

This view class,available on UNIX? systems only,allows you to get and set attributes specific to POSIX (Portable Operating System Interface). Its?readAttributes()?method returns a?PosixFileAttributes?instance containing details of the owner,group owner,and file permissions for this file (those you would normally set using the UNIX?chmod?command). The view also provides?setOwner(UserPrincipal),setGroup(GroupPrincipal),and?setPermissions(Set)?methods to modify these attributes.

UserDefinedFileAttributeView?and?String

This view class,available only on Windows,allows you to get and set?extended attributes?on files. These attributes are unlike the others in that they are just name-value pairs and can be set to anything you wish. This can be useful if you want to add some hidden metadata to a file without altering the file's content. The view provides a?list()?method that returns a?List?of?String?names of the extended attributes for the relevant file.

To get the contents of a particular attribute once you have its name,the view has a?size(String name)?method to return the size of the attribute's value and a?read(String name,ByteBuffer dest)?method to read the attribute value into the?ByteBuffer. The view also provides awrite(String name,ByteBuffer source)?method to create or alter an attribute,and also a?delete(String name)?method to remove an existing attribute entirely.

This is probably the most interesting new attribute view because it allows you to add attributes with arbitrary?String?names and?ByteBuffervalues to files. That's right — its value is a?ByteBuffer,so you can store any binary data in there you want.

First,we'll get the attribute view:

To get a list of the user-defined attribute names for this file,we call the?list()?method on the view:

attribList = userView.list();

Once we have a particular attribute name we wish to get the associated value for,we allocate a?ByteBuffer?of the right size for the value and then call the view's?read(String,ByteBuffer)?method:

attribValue?now contains whatever data was stored for that particular attribute. To set your own attribute,you simply need to create yourByteBuffer?and fill it with whatever data you wish and then call the?write(String,ByteBuffer)?method on the view:

Writing an attribute either creates that attribute or overwrites an existing attribute with the same name.

And with that,we conclude the third and final example. Full example code demonstrating four of the attribute views (BasicFileAttributeView,FileOwnerAttributeView,?FileStoreSpaceAttributeView,and?UserDefinedAttributeView) is included in the sample code?.

In addition to the topics covered in this article are a number of other NIO.2 file APIs. With Java 7 comes the new ability to create,inspect,and modify symbolic links. There are also new classes allowing access to lower-level information about the file system,and even to supply providers (called?FileSystem?and?FileStore) to access any type of file system you wish.

In summary,NIO.2 gives Java developers a simple,consistent,and powerful set of APIs to interact with the file system. Its aim is to abstract away some of the complex platform-specific details of dealing with files and directories and to give programmers more power and flexibility,and it has achieved this well.

http://www.ibm.com/developerworks/java/library/j-nio2-1/index.html

http://www.ibm.com/developerworks/java/library/j-nio2-2/index.html?ca=dat

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读