JavaOne 2013 
Clean Sweep 
The File System 
Manish Maheshwari 
mmaheshwari@verisign.com 
Anirban Mukherjee 
amukherjee@verisign.com
Speakers 
Manish 
Software Architect, Verisign 
Anirban 
Software Architect, Verisign 
Verisign Public 2
Why another API for File Handling 
What's wrong with java.io.File? 
Verisign Public 3
Why another API for File Handling 
• Lack of Information on what’s going on 
• File operations are not atomic 
• No bulk access to file attributes 
• Doesn’t scale for Directory Listing 
• Missing basic file operations 
• Copying File vs Copying File Attributes 
Verisign Public 4
Why another API for File Handling 
• Limited support for file metadata 
• Limited support for Symbolic Links 
• No way to extend the API for custom File System 
implementations 
• No support for File Notifications 
Verisign Public 5
The NIO-2 API Design 
• Informative Exceptions 
• DirectoryNotEmptyException 
• FileSystemLoopException 
• Varargs 
• Files.newBufferedWriter(path, UTF_8, 
CREATE, WRITE, APPEND, DELETE_ON_CLOSE); 
Verisign Public 6
NIO-2 API 
• Packages 
• java.nio.file 
• java.nio.file.attribute 
• java.nio.file.spi 
• Path 
• File System Path 
• Files 
• Factory of most common static 
operations 
• FileSystem 
• Factory for objects to access 
elements of File System 
• FileStore 
• Underlying storage, device, etc. 
Verisign Public 7
Path 
• Represents an absolute or relative path 
• Iterable over Path elements 
• Immutable 
• Operations to: 
• Access Path Elements 
• Combine Paths 
• Compare Paths 
Verisign Public 8
Creating Path 
Path path = 
FileSystems.getDefault().getPath("/ 
foo"); 
Verisign Public 9
Creating Path 
Path path = Paths.get("/foo"); 
Verisign Public 10
Creating Path 
URI uri = URI.create("file:///foo"); 
Path path = Paths.get(uri); 
Verisign Public 11
Creating Path 
File file = new File("foo"); 
Path path = file.getPath(); 
Verisign Public 12
Access Path Elements 
Path path = Paths.get("/","foo","bar","x"); 
Path file = path.getFileName(); 
Path parent = path.getParent(); 
Path root = path.getRoot(); 
Path subpath = path.subpath(1,3); 
Verisign Public 13
Access Path Elements 
Path path = Paths.get("top","foo","bar","x"); 
for (Path element : path ) { 
print("%s%n", element); 
} 
top 
foo 
bar 
x 
Verisign Public 14
Combine Paths 
Path top = Paths.get("/", "foo"); 
Path bar = top.resolve("bar"); 
Path baz = top.resolveSibling("baz"); 
Path qux = Paths.get("top","baz","qux"); 
Path rel = top.relativize(qux); 
../baz/quz 
Verisign Public 15
Test Paths 
Path path = Paths.get("top", "foo"); 
boolean isTop = path.startsWith("to"); 
boolean isPot = path.endsWith("pot"); 
boolean isAbs = path.isAbsolute(); 
Verisign Public 16
Other Operations 
Path path = … 
Path normal = path.normalize(); 
Path abs = path.toAbsolutePath(); 
Path real = path.toRealPath(); 
URI uri = path.toURI(); 
File file = path.toFile(); 
Verisign Public 17
Files 
• Static operations that operate on Files 
• Most operations expect Path as an argument 
• SymLink aware 
• Accept Standard Options 
• Operations for 
• Reading and Writing files 
• Streams, Readers, Writers 
• Symbolic Links 
• Working on Directory 
Verisign Public 18
Files 
• Mostly delegates to the FileSystemProvider SPI 
• Throws meaningful exceptions on failure 
Verisign Public 19
Files: Basic Operations 
Path file = Files.createFile(path); 
Path dir = Files.createDirectory(pathDir); 
Path dir = Files.createDirectories(pathDir); 
Verisign Public 20
Files: Basic Operations 
import static java.nio.charset.StandardCharsets.*; 
List<String> lines = Files.readAllLines(file, 
UTF_8); 
byte[] bytes = Files.readAllBytes(file); 
Verisign Public 21
Reader and Writer 
import java.nio.file.StandardOpenOption.*; 
Path file = … 
BufferedReader reader = 
Files.newBufferedReader(file, UTF_8); 
BufferedWriter writer = 
Files.newBufferedWriter(file, UTF_16, CREATE_NEW); 
Verisign Public 22
Copy and Open Options 
Verisign Public 23
Streams 
import java.nio.file.StandardOpenOption.*; 
Path file = … 
InputStream is = Files.newInputStream(file); 
OutputStream os = Files.newOutputStream(file); 
OutputStream osAppend = 
Files.newOutputStream(file, CREATE, APPEND); 
Verisign Public 24
Symbolic Links 
Path link = Paths.get("top", "link"); 
Path target = Paths.get("top", "foo", "tar"); 
Files.createSymbolicLink(link, target); 
Verisign Public 25
Symbolic Links 
Path link = Paths.get("top", "link"); 
boolean isSymLink = Files.isSymbolicLink(link); 
Path tar = Files.readSymbolicLink(link); 
Verisign Public 26
Symbolic Links 
Path p1 = … 
Path p2 = … 
boolean isSame = Files.isSameFile(p1, p2); 
Verisign Public 27
File Operations 
Files.delete(path); 
Files.deleteIfExists(path); 
Verisign Public 28
File Operations 
Path source = … 
Path target = … 
Files.copy(source, target); 
Verisign Public 29
File Operations 
Path source = … 
Path target = … 
Files.move(source, target); 
Verisign Public 30
File Operations 
import static java.nio.file.StandardCopyOption.*; 
Path source = … 
Path target = … 
Files.copy(source, target, 
ATOMIC_MOVE, REPLACE_EXISTING, COPY_ATTRIBUTES); 
Verisign Public 31
File Attributes 
• Meta data of files 
• Example 
• Created, Updated, Access timestamps 
• rwxr--r-- 
• Defined by Platform and File Systems 
Verisign Public 32
File Attributes 
• BasicFileAttributes 
• Supported by all platforms 
• TimeStamps, FileTypes, size, filekey 
• DosFileAttributes 
• Hidden, archive, readonly, system 
• PosixFileAttributes 
• Owner, group, other permission sets 
Verisign Public 33
File Attributes 
Verisign Public 34
File Attributes 
BasicFileAttributes basicAttr = 
Files.readAttributes(path, BasicFileAttributes.class); 
String key = basicAttr.fileKey(); 
long size = basicAttr.size(); 
boolean isDirectory = basicAttr.isDirectory(); 
FileTime lastModified = basicAttr.lastModifiedTime(); 
Verisign Public 35
File Attributes 
PosixFileAttributes posixAttr = 
Files.readAttributes(path, PosixFileAttributes.class); 
UserPrincipal owner = posixAttr.owner(); 
GroupPrincipal group = posixAttr.group(); 
String perms = PosixFilePermissions.toString(posixAttr.permissions())); 
Files.setPosixFilePermissions(path, 
PosixFilePermissions.fromString("rwxrwxrwx")); 
Verisign Public 36
Directory Listing 
• Efficient iteration of directory listings 
• Scales for large directories, remote file systems, etc. 
• In-built filter support 
• glob 
• regex 
• Custom Filter 
Verisign Public 37
Directory Listing 
try 
(DirectoryStream<Path> dirStream = 
Files.newDirectoryStream(dir,"*c*")) 
{ 
for (Path path : dirStream) { 
print("%s%n", path.toAbsolutePath()); 
} 
} 
Verisign Public 38
Directory Listing 
DirectoryStream.Filter<Path> filter = 
new DirectoryStream.Filter<Path>() { 
public boolean accept(Path entry) throws IOException { 
return Files.size(entry) > 1024; 
} 
}; 
try 
(DirectoryStream<Path> dirStream = Files.newDirectoryStream(dir,filter)) 
{ 
… 
} 
Verisign Public 39
Walk the File Tree 
• Visitor pattern that walks the file tree 
• Files.walkFileTree(start, fileVisitor) 
• start: node to begin from 
• fileVisitor: defines operation to perform on nodes 
• Depth first traversal 
Verisign Public 40
Walk the File Tree 
• FileVisitor callbacks: 
• preVisitDirectory 
• visitFile 
• postVisitDirectory 
• visitFileFailed 
• Enum FileVisitResult 
• CONTINUE 
• TERMINATE 
• SKIP_SUBTREE 
• SKIP_SIBLINGS 
Verisign Public 41
Walk the File Tree 
Path start = Paths.get("/foo/bar"); 
Files.walkFileTree(start, new SimpleFileVisitor<Path>(){ 
public FileVisitResult preVisitDirectory(Path dir, 
BasicFileAttributes attrs) throws IOException { 
print("preVisitDirectory: %s%n", dir); 
return FileVisitResult.CONTINUE; 
} 
public FileVisitResult visitFile(Path file, 
BasicFileAttributes attrs) throws IOException { 
print("visitFile: %s%n", file); 
return FileVisitResult.CONTINUE; 
} 
}); 
Verisign Public 42
Watch Service 
• Watch a file system for changes 
• Creates, update, delete 
• Uses native notifications 
• Falls back to polling 
Verisign Public 43
Watch Service 
Verisign Public 44
Watch Service Registration 
WatchService watcher = 
FileSystems.getDefault().newWatchService(); 
Path dir = … 
WatchKey watchKey = dir.register(watcher, ENTRY_MODIFY); 
Verisign Public 45
Watch Service Polling 
boolean keepWatching = true; 
while(keepWatching){ 
WatchKey key = watcher.poll(10, TimeUnit.SECONDS); 
for (WatchEvent<?> event: key.pollEvents()) { 
if (event.kind() == ENTRY_MODIFY) { 
Path name = (Path) event.context(); 
… 
} 
} 
key.reset(); 
} 
Verisign Public 46
Watch Service … Things to Watch in Real World 
• Sub-directories are not watched 
• Use Files.walkFileTree to register subdirectories upon 
visitFile() 
• Some editors create a new file when updating 
• Expecting an Update, but received Delete + Create events 
• Some file systems create a zero byte file initially 
• Expecting a Create, but observed Create + Update events 
Verisign Public 47
Custom File System 
• Allows creation of custom file systems 
• FileSystemProvider 
• Zip File System Provider is shipped as a reference 
implementation 
• Open Source implementations 
Verisign Public 48
Conclusion …. Final Thoughts 
• NIO-2 works consistently across platforms 
• Supports new operations 
• Supports bulk access to File Attributes 
• Better exceptions 
• SPI for custom provider interface 
Verisign Public 49
Thank You 
© 2013 VeriSign, Inc. All rights reserved. VERISIGN and other trademarks, service marks, and 
designs are registered or unregistered trademarks of VeriSign, Inc. and its subsidiaries in the United 
States and in foreign countries. All other trademarks are property of their respective owners.

Clean Sweep FileSystem - Java NIO 2

  • 1.
    JavaOne 2013 CleanSweep The File System Manish Maheshwari mmaheshwari@verisign.com Anirban Mukherjee amukherjee@verisign.com
  • 2.
    Speakers Manish SoftwareArchitect, Verisign Anirban Software Architect, Verisign Verisign Public 2
  • 3.
    Why another APIfor File Handling What's wrong with java.io.File? Verisign Public 3
  • 4.
    Why another APIfor File Handling • Lack of Information on what’s going on • File operations are not atomic • No bulk access to file attributes • Doesn’t scale for Directory Listing • Missing basic file operations • Copying File vs Copying File Attributes Verisign Public 4
  • 5.
    Why another APIfor File Handling • Limited support for file metadata • Limited support for Symbolic Links • No way to extend the API for custom File System implementations • No support for File Notifications Verisign Public 5
  • 6.
    The NIO-2 APIDesign • Informative Exceptions • DirectoryNotEmptyException • FileSystemLoopException • Varargs • Files.newBufferedWriter(path, UTF_8, CREATE, WRITE, APPEND, DELETE_ON_CLOSE); Verisign Public 6
  • 7.
    NIO-2 API •Packages • java.nio.file • java.nio.file.attribute • java.nio.file.spi • Path • File System Path • Files • Factory of most common static operations • FileSystem • Factory for objects to access elements of File System • FileStore • Underlying storage, device, etc. Verisign Public 7
  • 8.
    Path • Representsan absolute or relative path • Iterable over Path elements • Immutable • Operations to: • Access Path Elements • Combine Paths • Compare Paths Verisign Public 8
  • 9.
    Creating Path Pathpath = FileSystems.getDefault().getPath("/ foo"); Verisign Public 9
  • 10.
    Creating Path Pathpath = Paths.get("/foo"); Verisign Public 10
  • 11.
    Creating Path URIuri = URI.create("file:///foo"); Path path = Paths.get(uri); Verisign Public 11
  • 12.
    Creating Path Filefile = new File("foo"); Path path = file.getPath(); Verisign Public 12
  • 13.
    Access Path Elements Path path = Paths.get("/","foo","bar","x"); Path file = path.getFileName(); Path parent = path.getParent(); Path root = path.getRoot(); Path subpath = path.subpath(1,3); Verisign Public 13
  • 14.
    Access Path Elements Path path = Paths.get("top","foo","bar","x"); for (Path element : path ) { print("%s%n", element); } top foo bar x Verisign Public 14
  • 15.
    Combine Paths Pathtop = Paths.get("/", "foo"); Path bar = top.resolve("bar"); Path baz = top.resolveSibling("baz"); Path qux = Paths.get("top","baz","qux"); Path rel = top.relativize(qux); ../baz/quz Verisign Public 15
  • 16.
    Test Paths Pathpath = Paths.get("top", "foo"); boolean isTop = path.startsWith("to"); boolean isPot = path.endsWith("pot"); boolean isAbs = path.isAbsolute(); Verisign Public 16
  • 17.
    Other Operations Pathpath = … Path normal = path.normalize(); Path abs = path.toAbsolutePath(); Path real = path.toRealPath(); URI uri = path.toURI(); File file = path.toFile(); Verisign Public 17
  • 18.
    Files • Staticoperations that operate on Files • Most operations expect Path as an argument • SymLink aware • Accept Standard Options • Operations for • Reading and Writing files • Streams, Readers, Writers • Symbolic Links • Working on Directory Verisign Public 18
  • 19.
    Files • Mostlydelegates to the FileSystemProvider SPI • Throws meaningful exceptions on failure Verisign Public 19
  • 20.
    Files: Basic Operations Path file = Files.createFile(path); Path dir = Files.createDirectory(pathDir); Path dir = Files.createDirectories(pathDir); Verisign Public 20
  • 21.
    Files: Basic Operations import static java.nio.charset.StandardCharsets.*; List<String> lines = Files.readAllLines(file, UTF_8); byte[] bytes = Files.readAllBytes(file); Verisign Public 21
  • 22.
    Reader and Writer import java.nio.file.StandardOpenOption.*; Path file = … BufferedReader reader = Files.newBufferedReader(file, UTF_8); BufferedWriter writer = Files.newBufferedWriter(file, UTF_16, CREATE_NEW); Verisign Public 22
  • 23.
    Copy and OpenOptions Verisign Public 23
  • 24.
    Streams import java.nio.file.StandardOpenOption.*; Path file = … InputStream is = Files.newInputStream(file); OutputStream os = Files.newOutputStream(file); OutputStream osAppend = Files.newOutputStream(file, CREATE, APPEND); Verisign Public 24
  • 25.
    Symbolic Links Pathlink = Paths.get("top", "link"); Path target = Paths.get("top", "foo", "tar"); Files.createSymbolicLink(link, target); Verisign Public 25
  • 26.
    Symbolic Links Pathlink = Paths.get("top", "link"); boolean isSymLink = Files.isSymbolicLink(link); Path tar = Files.readSymbolicLink(link); Verisign Public 26
  • 27.
    Symbolic Links Pathp1 = … Path p2 = … boolean isSame = Files.isSameFile(p1, p2); Verisign Public 27
  • 28.
    File Operations Files.delete(path); Files.deleteIfExists(path); Verisign Public 28
  • 29.
    File Operations Pathsource = … Path target = … Files.copy(source, target); Verisign Public 29
  • 30.
    File Operations Pathsource = … Path target = … Files.move(source, target); Verisign Public 30
  • 31.
    File Operations importstatic java.nio.file.StandardCopyOption.*; Path source = … Path target = … Files.copy(source, target, ATOMIC_MOVE, REPLACE_EXISTING, COPY_ATTRIBUTES); Verisign Public 31
  • 32.
    File Attributes •Meta data of files • Example • Created, Updated, Access timestamps • rwxr--r-- • Defined by Platform and File Systems Verisign Public 32
  • 33.
    File Attributes •BasicFileAttributes • Supported by all platforms • TimeStamps, FileTypes, size, filekey • DosFileAttributes • Hidden, archive, readonly, system • PosixFileAttributes • Owner, group, other permission sets Verisign Public 33
  • 34.
  • 35.
    File Attributes BasicFileAttributesbasicAttr = Files.readAttributes(path, BasicFileAttributes.class); String key = basicAttr.fileKey(); long size = basicAttr.size(); boolean isDirectory = basicAttr.isDirectory(); FileTime lastModified = basicAttr.lastModifiedTime(); Verisign Public 35
  • 36.
    File Attributes PosixFileAttributesposixAttr = Files.readAttributes(path, PosixFileAttributes.class); UserPrincipal owner = posixAttr.owner(); GroupPrincipal group = posixAttr.group(); String perms = PosixFilePermissions.toString(posixAttr.permissions())); Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxrwxrwx")); Verisign Public 36
  • 37.
    Directory Listing •Efficient iteration of directory listings • Scales for large directories, remote file systems, etc. • In-built filter support • glob • regex • Custom Filter Verisign Public 37
  • 38.
    Directory Listing try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(dir,"*c*")) { for (Path path : dirStream) { print("%s%n", path.toAbsolutePath()); } } Verisign Public 38
  • 39.
    Directory Listing DirectoryStream.Filter<Path>filter = new DirectoryStream.Filter<Path>() { public boolean accept(Path entry) throws IOException { return Files.size(entry) > 1024; } }; try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(dir,filter)) { … } Verisign Public 39
  • 40.
    Walk the FileTree • Visitor pattern that walks the file tree • Files.walkFileTree(start, fileVisitor) • start: node to begin from • fileVisitor: defines operation to perform on nodes • Depth first traversal Verisign Public 40
  • 41.
    Walk the FileTree • FileVisitor callbacks: • preVisitDirectory • visitFile • postVisitDirectory • visitFileFailed • Enum FileVisitResult • CONTINUE • TERMINATE • SKIP_SUBTREE • SKIP_SIBLINGS Verisign Public 41
  • 42.
    Walk the FileTree Path start = Paths.get("/foo/bar"); Files.walkFileTree(start, new SimpleFileVisitor<Path>(){ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { print("preVisitDirectory: %s%n", dir); return FileVisitResult.CONTINUE; } public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { print("visitFile: %s%n", file); return FileVisitResult.CONTINUE; } }); Verisign Public 42
  • 43.
    Watch Service •Watch a file system for changes • Creates, update, delete • Uses native notifications • Falls back to polling Verisign Public 43
  • 44.
  • 45.
    Watch Service Registration WatchService watcher = FileSystems.getDefault().newWatchService(); Path dir = … WatchKey watchKey = dir.register(watcher, ENTRY_MODIFY); Verisign Public 45
  • 46.
    Watch Service Polling boolean keepWatching = true; while(keepWatching){ WatchKey key = watcher.poll(10, TimeUnit.SECONDS); for (WatchEvent<?> event: key.pollEvents()) { if (event.kind() == ENTRY_MODIFY) { Path name = (Path) event.context(); … } } key.reset(); } Verisign Public 46
  • 47.
    Watch Service …Things to Watch in Real World • Sub-directories are not watched • Use Files.walkFileTree to register subdirectories upon visitFile() • Some editors create a new file when updating • Expecting an Update, but received Delete + Create events • Some file systems create a zero byte file initially • Expecting a Create, but observed Create + Update events Verisign Public 47
  • 48.
    Custom File System • Allows creation of custom file systems • FileSystemProvider • Zip File System Provider is shipped as a reference implementation • Open Source implementations Verisign Public 48
  • 49.
    Conclusion …. FinalThoughts • NIO-2 works consistently across platforms • Supports new operations • Supports bulk access to File Attributes • Better exceptions • SPI for custom provider interface Verisign Public 49
  • 50.
    Thank You ©2013 VeriSign, Inc. All rights reserved. VERISIGN and other trademarks, service marks, and designs are registered or unregistered trademarks of VeriSign, Inc. and its subsidiaries in the United States and in foreign countries. All other trademarks are property of their respective owners.