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.