dagblog.
← Archive

New APIs for files and other I/O


I’d started to think java.io.File would be our only abstraction for dealing with the file system in Java forever. It’s a rather flawed abstraction, at that. Fortunately those of us who had to use it weren’t the only ones tearing our hair out. That led to JSR 203 More New I/O APIs for the Java Platform (“NIO.2”), which will be part of JDK 7. The new API covers three areas. Besides a better interface to the file system, it adds asynchronous I/O and fills out the socket-channel functionality.

The central types in the new java.nio.file and java.nio.file.attribute packages will be FileSystem, the main abstraction for working with the file system, Path, for a system-dependent directory or file path, and BasicFileAttributes, for metadata about a resource such as size, ACL and last modification time. The other classes are in the Javadoc.

The API is extensible, so we’ll be able to write a FileSystem implementation for our obscure file system exposed through a REST interface, for example. We’re also interested in working with the files themselves, specifically copying, moving, writing and reading them.

import static java.nio.file.StandardCopyOption.*;



Path source = Path.get("C:\\My Documents\\Stuff.odp");

Path target = Path.get("D:\\Backup\\MyStuff.odp");

source.copyTo(target);

source.copyTo(target, REPLACE_EXISTING, COPY_ATTRIBUTES);

Every operation in the new I/O API that can fail with an IOException actually throws one. Exceptional conditions no longer have to be signaled by a boolean return value, as in the old I/O API’s renameTo method, for example. The new API should be consistent about this. Since it also handles metadata for files and directories, it can deal reasonably with things like symbolic links.

One feature I found interesting is support for notifications and asynchronous I/O. The new WatchService class can watch a given entity for event types such as reads, deletions or changes. That will make it easy to respond to a file changing, for example.

WatchService watcher = FileSystems.getDefault().newWatchService();

Set events =

EnumSet.of(ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

WatchKey key = dir.register(watcher, events);

for (;;) {

 // wait for key to be signalled

 key = watcher.take();

 // process events

 for (WatchEvent ev: key.pollEvents()) {

 if (event.getType() == ENTRY_MODIFY) {

 //do something

 }

 }

 // reset key

 key.reset();

}

Asynchronous support lets us do things like copying a file asynchronously through an abstraction such as java.util.concurrent.Future or with a callback. But why go on when there’s so much material already?

Medium version

Related articles

Related CZ Podcast episodes