Some JSR 203 Examples
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/
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 is a DZone MVB and is not an employee of DZone and has posted 43 posts at DZone. You can read more from them at their website.
- Login or register to post comments
- 6042 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)










Comments
OtengiM replied on Thu, 2008/10/23 - 5:07am
Bernd Eckenfels replied on Thu, 2008/10/23 - 4:06pm
Steven 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 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: ecki
Alex Miller replied on Fri, 2008/10/24 - 12:06am
in response to: zynasis
Alex Miller replied on Fri, 2008/10/24 - 12:06am
in response to: dhergert
EddyJhon replied on Tue, 2009/04/28 - 8:06am
hookfi replied on Sun, 2009/05/31 - 7:41am
Seeker01 replied on Thu, 2009/06/11 - 8:21am
in response to: EddyJhon
beladona replied on Sat, 2009/06/20 - 7:17am
Marlet replied on Sun, 2009/06/21 - 4:31pm
I like the support for walking directories, a nice addition
Free Wii | Free Xbox 360 | Free PSP Go | Free Macbookmenexis replied on Tue, 2009/06/23 - 6:47pm
emad964 replied on Mon, 2009/06/29 - 4:37pm
jiji530 replied on Mon, 2009/06/29 - 10:07pm
superpan3721 replied on Sat, 2009/08/01 - 1:07am
DriftingStarr replied on Tue, 2009/08/25 - 1:45pm
Very helpful...maybe this will be too
Free PS3 Slim * Free PSP Go
John2009 replied on Mon, 2009/09/14 - 8:44am
sunrise1 replied on Sun, 2009/10/25 - 8:50am