Exploring the Path API – Java NIO enhancement in Java 7

All of us know that an instance of File doesn’t indicate a file in the file system, unless some one invokes a create or related methods. But its a kind of confusion- you talk about instance of File and then you also talk about file at the disk level. A new class was introduced in Java 7 as part of the NIO enhancements which allows to represent the files at the disk level in the memory/as part of objects in Java and this new class is the Path class. And I have used this class extensively in my posts about Files API here and here and also about WatchService API.

also read:

Path is an interface and there is a factory Paths which can be used to create instances of type Path. Lets look at some of the operations/functionality provided by Paths and Path classes.

Defining Path

Paths class provides a get(URI), get(String, String …) methods to obtain a Path instance for given file/directory.

Using Absolute Path
Path path1 = Paths.get("E:/Back Up/OSLabs/priority.c");

Path invalidPath = Paths.get("E:/Back Up/OSLabs/invalid");

try{
  System.out.println(invalidPath.toRealPath());
}
catch(NoSuchFileException ex){
  System.out.println(invalidPath.toString()+" not found");
}
//output: E:\Back Up\OSLabs\invalid not found

In the above example we have a valid path and another invalid path. These Path instances dont really check if the location uses if valid or not, but one can use toRealPath() which checks if the given path is valid or not.

Using Relative Path
Path relPath1 = Paths.get("test1");
Path relPath2 = Paths.get("test2");
System.out.println(relPath1.toRealPath());
//output: C:\Documents and Settings\Mohamed Sanaulla\My Documents\NetBeansProjects\JavaBeatSamples\test1
Using FileSystem to construct Path

Java 7 NIO enhancements added a new FileSystem and FileSystems class to get the instance of underlying file system. An instance of Path can also be created using getPath() method of the FileSystem class.

FileSystem fs = FileSystems.getDefault();
Path fsPath1 = fs.getPath("/dev/Test.java");
Path fsPath2 = fs.getPath("test1");
System.out.println(fsPath1.toRealPath());
System.out.println(fsPath2.toRealPath());
//output:
//C:\dev\Test.java
//C:\Documents and Settings\Mohamed Sanaulla\My Documents\NetBeansProjects\JavaBeatSamples\test1

What all information can be obtained from Path?

Path class provides methods to get the name of the file, the parent path of the file, the root of the file and also an Iterator to get different elements of the Path string. Lets look at an example below:

System.out.println("Information from the Path");
System.out.println("Path Name: "+path1.getFileName());
System.out.println("Path Parent: "+path1.getParent());
System.out.println("Path Root: "+path1.getRoot());
System.out.println("Number of elements in path: "+path1.getNameCount());
for ( int i = 0; i < path1.getNameCount(); i++){
  System.out.println("Element "+i+": "+path1.getName(i));
}
System.out.println("Subpath: "+path1.subpath(0,2));
/*
output:
Information from the Path
Path Name: priority.c
Path Parent: E:\Back Up\OSLabs
Path Root: E:\
Number of elements in path: 3
Element 0: Back Up
Element 1: OSLabs
Element 2: priority.c
Subpath: Back Up\OSLabs*/

Comparing Paths

One can compare the paths using equals() which checks for content equality, compareTo() which can be overridden for correct comparison and the Files.isSameFile method which can be used to check if the two path instances actually refer to the same file on the disk. An example for the same:

System.out.println("Path comparisions");
Path compPath1 = Paths.get("/dev/Test.java");
Path compPath2 = Paths.get("C:/dev/Test.java");
System.out.println("Using Equals: "+compPath1.equals(compPath2));
System.out.println("Using isSameFile: "+Files.isSameFile(compPath1, compPath2));
/*
Output:
Path comparisions
Using Equals: false
Using isSameFile: true
*/

In the above example though compPath1 and compPath2 represented same file their string content was different. Hence equals() told that they are different where as isSameFile told that they are same.

Converting Path to File and URI

One can convert the Path instance into URI format and also create a File instance out of it.

System.out.println("Path conversions");
System.out.println("String: "+fsPath1.toString());
System.out.println("URI: "+fsPath1.toUri());
File fileFsPath1 = fsPath1.toFile();
System.out.println("File: "+fileFsPath1.exists());
/*
Output:
Path conversions
String: \dev\Test.java
URI: file:///C:/dev/Test.java
File: true
*/

Combining different paths

We can create one base path and then build multiple paths from that base path using the resolve() method, something like:

System.out.println("Combining Paths");
Path basePath = Paths.get("C:/dev");
Path newPath1 = basePath.resolve("Test.java");
System.out.println("Same file? "+Files.isSameFile(compPath2, newPath1));
Path newPath2 = basePath.resolve("java/CloneTest.java");
System.out.println(newPath2.toRealPath());
/*
Output:
Combining Paths
Same file? true
C:\dev\java\CloneTest.java
*/

These were some of the APIs associated with Path class. Pro Java 7 NIO.2 addresses the three primary elements that offer new input/output (I/O) APIs in Java 7, giving you the skills to write robust, scalable Java applications.

Comments

comments

About Mohamed Sanaulla

In his day job he works on developing enterprise applications using ADF. He is also the moderator of JavaRanch forums and an avid blogger.

Trackbacks

  1. JavaPins says:

    Exploring the Path API – Java NIO enhancement in Java 7…

    Thank you for submitting this cool story – Trackback from JavaPins…

  2. [...] Path and Paths API: A brief overview of the Path and Paths classes and how these can be used to represent a file/directory. Also explained are the [...]

Speak Your Mind

*