Srikanth Technologies

Path Interface and Files class in NIO of Java 7.0

Java 7 introduced new file IO called "NIO.2 File System". Its classes are provided in a new package - java.nio.files.

In this blog we use a couple of new classes introduced in new IO of Java 7. Our primary focus is on Path and Files classes.

Path Interface

Path interface in Java 7 is similar to File class in Java 6.

The Java I/O File API, as it was originally created, was not written to be extended.

Many of the methods do not throw exceptions even when an error is encountered leaving developers wondering what's happening.

The following code in Java 6.0 will not throw any exception even if the file is not found in the filesystem.

 File f = new File("c:\\test.txt");
 f.delete();
Shown below is the code in Java 7.0 using Path class but it throws exception when file is not found.
 
 Path fp = Paths.get("c:\\test.txt");   // get Path object
 Files.delete(fp);  // delete file represented by path object

output
======
Exception in thread "main" java.nio.file.NoSuchFileException: c:\test.txt
Method Description
Path getFileName() Returns the name of the file or directory denoted by this path as a Path object
FileSystem getFileSystem() Returns the file system that created this object
Path getName(int index) Returns a name element of this path as a Path object
int getNameCount() Returns the number of name elements in the path
Path getParent() Returns the parent path, or null if this path does not have a parent
Iterator<Path>iterator() Returns an iterator over the name elements of this path
WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events) Registers the file located by this path with a watch service
Path toAbsolutePath() Returns a Path object representing the absolute path of this path
File toFile() Returns a File object representing this path
URI toUri() Returns a URI to represent this path

The following code shows some other new methods of Path class.


        Path p = Paths.get("c:\\jdk7.0\\bin\\javac.exe");
        System.out.println( p.getNameCount());    // 3
        System.out.println( p.getName(1));        // bin

        System.out.println( p.getFileSystem().getClass());  // display file system - sun.nio.fs.WindowsFileSystem

        File f = p.toFile();  // convert to File object

Files class

Files class provides static methods that operate on files and directories.

The following are the important methods of Files class.

Method Description
static Path copy(Path source, Path target, CopyOption... options) Copies a file to a target file
static void delete(Path path) Deletes a file.
static boolean deleteIfExists(Path path) Deletes a file if it exists.
static boolean isDirectory(Path path, LinkOption... options) Tests whether a file is a directory
static Path move(Path source, Path target, CopyOption... options) Moves or renames a file to a target file
static DirectoryStream<Path> newDirectoryStream(Path dir) Opens a directory, returning a DirectoryStream to iterate over all entries in the directory
static String probeContentType(Path path) Probes the content type of a file
static List<String> readAllLines(Path path, Charset cs) Reads all lines from a file
static long size(Path path) Returns the size of a file (in bytes)
static Path walkFileTree(Path start, FileVisitor<? super Path> visitor) Walks a file tree

The following example shows how to use newDirectoryStream() to get list of files from the given path. Though listFiles() method of File class provides this functionality, DirectoryStream is more scalable.


        Path path = Paths.get("c:\\jdk7.0");
       
        //  take files from jdk7.0
        try (DirectoryStream<Path>  directory =  Files.newDirectoryStream(path))   // Closes stream at the end (ARM)
        {
           for (Path file :  directory) 
              System.out.println(file.getFileName()); 
        }
The following code shows how to get the list of lines from a file using readAllLines() method.
         Path p = Paths.get("c:\\jdk7.0\\names.txt");
        System.out.println("Size : "  + Files.size(p));
           
        List<String> lines = Files.readAllLines(p, Charset.defaultCharset());
        for(String line : lines)
             System.out.println(line);

The following example shows how to display the list of files from the given tree in the file system. It walks through the tree that starts with c:\jdk7.0 and displays all files and folder present within jdk7.0 folder.

Method walkFileTree() takes path to start with and an object of a class that extends SimpleFileVisitor class. For each file that is visited, visitFile() method is called. Before a directory is processed, preVisitDirectory() method is called. After directory is processed, postVisitDirectory() method is called.


import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import static java.nio.file.FileVisitResult.CONTINUE;

public class WalkTree {
    public static void main(String[] args) throws Exception 
    {
        Path p = Paths.get("c:\\jdk7.0");
        PrintFiles pf= new PrintFiles();
        Files.walkFileTree(p,pf);
    }
}

class PrintFiles extends SimpleFileVisitor<Path> {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attr) {
        System.out.println( "File :" + file.getFileName());
        return CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException ioe) throws IOException {
        System.out.printf("Processed Directory: %s\n", dir.getFileName());
        return CONTINUE;
    }

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes bfa) throws IOException {
        System.out.printf("About to process directory: %s\n", dir.getFileName() );
        return CONTINUE;
    }
}