Alex Miller lives in St. Louis. He writes code for a living and currently work for Terracotta Tech on the Terracotta open-source Java clustering product. Prior to Terracotta he worked at BEA Systems and was Chief Architect at MetaMatrix. His main language for the last decade has been Java, although Alex have been paid to program in several languages over the years (C++, Python, Pascal, etc). Alex has posted 43 posts at DZone. You can read more from them at their website. View Full User Profile

Some JSR 203 Examples

10.23.2008
| 22373 views |
  • submit to reddit

I’ve been preparing for some upcoming Java SE 7 Preview presentations I’m doing on the No Fluff tour in Reston, VA and Chicago, IL. I worked up some JSR 203 (the new new I/O JSR) examples and thought I would drop them here in case they were useful. These are based on the latest Javadocs available on the project page (b97).

I’m not putting much context here. You can read a well written summary from Elliotte Rusty Harold or watch the JavaOne presentation. Or come see my talks. :)

I actually did a talk like this about 18 months ago and went back and looked at it and the API has changed a lot since then. In many ways, it’s been simplified and consolidated much to its overall benefit. In just the last few months, there’s been a lot of polishing, especially making better use of enums and little things like that. Some of those changes are good and some are pretty long-winded in use.

Path is the new File. It’s a little more nuanced than that, but Path is definitely the center of the new filesystem API. Here’s some basic fiddling with it:

import java.nio.file.*;   

// FileSystems -> FileSystem -> Path
FileSystem fileSystem = FileSystems.getDefault();
Path homeDir = fileSystem.getPath(“/Users/amiller”);

// Shortcut with Paths helper class
Path homeDir = Paths.get(“/Users/amiller”);

// Resolve one path in terms of another
Path relativeTemp = Paths.get(“temp”);
Path absoluteTemp = relativeTemp.resolve(homeDir);

// Get relative path from a base
Path absoluteProfile = Paths.get(“/Users/amiller/.profile”);
Path relativeProfile = absoluteProfile.relativize(homeDir);
assert relativeProfile.isRelative();
assert relativeProfile.getNameCount() == 1;

 

And here’s an example of opening and appending to a file:

import java.io.*;   
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKind.*;
Path journal = Paths.get("/Users/amiller/journal.txt");

OutputStream stream = journal.newOutputStream(CREATE, APPEND);

try { 

writeEntry(stream); // normal stuff
} finally {
stream.close();
}

 

One nice thing is that copy and move are built-in (at long, long last):

import java.nio.file.*;   

Path home = Paths.get("/Users/amiller");
Path secrets = home.resolve("secrets.txt");

// Steal secrets
secrets.copyTo(home.resolve("stolenSecrets.txt"));

// Hide secrets
secrets.moveTo(Paths.get("/Users/dvader/secrets.txt"));

 

There is lots of support now for walking directories - here are some internal and external iterator versions:

Path music = Paths.get("/Users/amiller/files/music");   

// External iterator
DirectoryStream<Path> mp3s = music.newDirectoryStream(“*.mp3”);
try {
for(Path entry : mp3s)
System.out.println(entry.getName());
} finally {
mp3s.close();
}

// Internal iterator
Files.withDirectory(music, “*.mp3”, new FileAction<Path>() {
public void invoke(Path entry) {
System.out.println(entry.getName());
}
}

 

And there is even a visitor pattern for walking a directory recursively (with support for following symbolic links, checking for cycles, etc):

Path itunes = Paths.get("/Users/amiller/Music/iTunes/iTunes Music");

  
public class Mp3Visitor extends SimpleFileVisitor<Path> {
private Path root;
public Mp3Visitor(Path root) {
this.root = root;
}

public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println(root.relativize(file));
}
}

Files.walkFileTree(itunes, new Mp3Visitor(itunes));

And of course, we also finally have support for accessing posix file attributes as part of the API (and some other common attribute sets and extensible support for other pluggable file systems):

Path file = Paths.get(“/usr/bin/perl”);   

// true here means follow symbolic links
BasicFileAttributes attrs = Attributes.readPosixFileAttributes(file, true);
Set<PosixFilePermission> perms = attrs.permissions();

System.out.format("%s %s %s", PosixFilePermission.toString(attrs.permissions()), attrs.owner(), attrs.group());

// rwxr-xr-x root wheel

Finally, there is now support for generic “watch services” to watch file events in a directory (with efficient support depending on the platform):

import static java.nio.file.StandardWatchEventKind.*;   
Path deploy = Paths.get(“deploy”);
WatchService watcher = FileSystems.getDefault().newWatchService();
WatchKey key = deploy.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY );

for(;;) {
key = watcher.take(); // blocks, also can poll
for(WatchEvent<?> event : key.pollEvents()) {
switch(event.kind()) {
case ENTRY_CREATE:
Path file = (Path)event.getContext(); //relative to deploy
// deploy new stuff
case ENTRY_MODIFY: ...
case ENTRY_DELETE: ...
}
}
key.reset(); // reset after processing
}

 

If anyone spots any bugs, please let me know.

From http://tech.puredanger.com/

Published at DZone with permission of its author, Alex Miller.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Otengi Miloskov replied on Thu, 2008/10/23 - 5:07am

Very nice and it looks pretty easy to use, Congratulations!. Java is moving forward.

Bernd Eckenfels replied on Thu, 2008/10/23 - 4:06pm

Cool, Append Support. Is renameTo() throwing usefull exceptions? Like this: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5036327

Steven Baker replied on Thu, 2008/10/23 - 5:27pm

there really isnt much new useful features here. really just looks like some utils that could be made with current java.

i'm disappointed

David Hergert replied on Thu, 2008/10/23 - 11:14pm

Last example, line 9... should that be ev.kind()?  Don't see where "event" is defined.

BTW, liking what I'm seeing with the new api

Alex Miller replied on Fri, 2008/10/24 - 12:01am in response to: Bernd Eckenfels

@Bernd: In general, the file operations on Path (like copyTo, moveTo, delete) now throw more descriptive subclasses of IOException, like FileAlreadyExistsException. 

Alex Miller replied on Fri, 2008/10/24 - 12:06am in response to: Steven Baker

@Steven: It may be hard to see as I've only shown about 10% of the new stuff here in the file system API and haven't even touched the new asynch or multicast support in NIO.  But there really are a tremendous number of new features - better API taking using of Java 5+, better security, much deeper support for platform-specific stuff, etc.  I'd urge you to take a deeper look.

Alex Miller replied on Fri, 2008/10/24 - 12:06am in response to: David Hergert

@David: Yup.  Fixed.

Carla Brian replied on Sun, 2012/06/24 - 5:32pm

What I like about this one is that JRE 7 provides the libraries, the Java Virtual Machine, and other components to run applets and applications written in the Java programming language. - Mercy Ministries

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.