Saturday, May 13, 2023

Difference between getPath(), getCanonicalPath() and getAbsolutePath() of File in Java - Example

File API is a very important one in Java, it gives access to the File system to Java programs. Though Java's file API is rich, there are a lot of subtleties to know when you use them. One of the common query programmer's has about file path is difference between getPath(), getCanonicalPath() and getAbsolutePath() methods, why there are three methods to get file path and what happens if you call getPath() in place of getCanonicalPath(). By the way, before understanding the difference between getPath(), getAbsolutePath() and getCanonicalPath() let's understand the concept behind these methods, i.e. the difference between path, absolute path, and canonical path.

In general, a path is a way to get to a particular file or directory in a file system, it can be absolute (also known as a full path) or relative e.g. relative to the current location. Absolute path defines a path from the root of the file system e.g. C:\\ or D:\\ in Windows and from / in UNIX based operating systems e.g. Linux or Solaris.

The canonical path is a little bit tricky because all canonical path is absolute, but vice-versa is not true. It actually defines a unique absolute path to the file from the root of the file system. For example, C://temp/names.txt is a canonical path to names.txt in Windows, and /home/javinpaul/test/names.txt is a canonical path in Linux.

On the other hand, there can be many absolute path to the same file, including the canonical path which has just been seen. For example, another absolute path to the same file in Windows can be C://temp/./names.txt; similarly in UNIX /home/javinpaul/test/./names.txt is another absolute path to the same file. So you can say that the absolute path may contain meta characters like . and .. to represent current and parent directory.

In rest of this article, we will learn difference between getPath(), getAbsolutePath() and getCanonical() Path by looking at values it return for a particular file.



What is Absolute, Relative and Canonical Path

You often heard the term, absolute, canonical and relative path while dealing with files in UNIX, Windows, Linux or any file system. These are three common ways to reference any particular file in a script or program. 

If you are a programmer, writing script then you know how using absolute path can make your script rigid and in-flexible, infact using absolute path, infamously known as hard-coding path in script is one of the bad coding practice in programmer's dictionary.

 An absolute path is complete path to a particular file such as C:\temp\abc.txt. The definition of absolute pathname is also system dependent. On UNIX systems, a pathname is absolute if its prefix is "/". On Win32 systems, a pathname is absolute if its prefix is a drive specifier followed by "\\", or if its prefix is "\\".

For example, we have two directories: temp and temp1 and test.txt file is in temp directory.
C:\temp
C:\temp1

In Java under Windows, you may have the following possible absolute paths that refer to the same file test.txt.

 C:\temp\test.txt
C:\temp\test.txt
C:\temp\TEST.TXT
C:\temp\.\test.txt
C:\temp1\..\temp\test.txt

On the other hand, relative path is relative to the directory you are in, known as current directory. So if you are in the above directory, then if you reference file test.txt as relative, it assumes the same directory you are in. When you do ../ then it goes back one directory, also known as parent directory. Canonical paths are a bit harder. For starters, all canonical paths are absolute (but not all absolute paths are canonical). 

A single file existing on a system can have many different paths that refer to it, but only one canonical path. Canonical gives a unique absolute path for a given file. The details of how this is achieved are probably system-dependent. 

For the above example, we have one and only one canonical path: C:\temp\test.txt, Remember in Java you can UNIX style forward slash (/) use path separator or you can even get operating systems path separator using file.separator system property, a key to write truly platform independent Java application.


Difference between getPath(), getAbsolutePath() and getCanonicalPath() in Java

Once you understand difference between absolute, canonical and relative path, it would be very easy to differentiate between these three method, because they actually return path, absolute and canonical path. In short, here is key difference between them :

  1. The first method, getPath()  return a String which denotes the path that is used to create associated File object, and it may be relative to current directory.
  2. The second method, getAbsolutePath() returns the path string after resolving it against the current directory if it's relative, resulting in a fully qualified path.
  3. The third method, getCanonicalPath() returns the path string after resolving any relative path against current directory, and removes any relative path element e.g. (. and ..), and any file system links to return a path which the file system considers the canonical means to reference the file system object to which it points.

Also remember that , each of above two method has a File equivalent which returns the corresponding File object e.g. getAbsoluteFile() and getCanonicalFile() which returns same thing.


Difference between Path, absolute Path and Relative path java



getPath() vs getAbsolutePath() vs getCanonicalPath()

The following example shows how there can be many different paths (and absolute paths) to the same file, which all have the exact same canonical path. Thus canonical path is useful if you want to know if two different paths point to the same file or not.

import java.io.File;

/**
 * Java program to show difference between path, absolute path and canonical
 * path related to files in Java. File API provides three methods to
 * java.io.File class getPath(), getAbsolutePath() and getCanonicalPath() and
 * this program just explain what those method returns.
 *
 * @author Javin Paul
 */
public class PathDemo {

    public static void main(String args[]) {
        System.out.println("Path of the given file :");
        File child = new File(".././Java.txt");
        displayPath(child);

        File parent = child.getParentFile();
        System.out.println("Path of the parent file :");
        displayPath(parent);
    }

    public static void displayPath(File testFile) {
        System.out.println("path : " + testFile.getPath());
        System.out.println("absolute path : " + testFile.getAbsolutePath());

        try {
            System.out.println("canonical path : " 
                      + testFile.getCanonicalPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Output:
Path of the given file :
path : ..\.\Java.txt
absolute path : C:\Users\WINDOWS 8\workspace\Demo\..\.\Java.txt
canonical path : C:\Users\WINDOWS 8\workspace\Java.txt

Path of the parent file :
path : ..\.
absolute path : C:\Users\WINDOWS 8\workspace\Demo\..\.
canonical path : C:\Users\WINDOWS 8\workspace

That's all about difference between getPath(), getAbsolutePath() and getCanonicalPath() in Java. In the course, we have also learned difference between path, absolute path, and canonical path. What you need to remember is that getPath() gives you the path on which File object is created, which may or may not be relative; getAbsolutePath() gives an absolute path to the file; and getCanonicalPath() gives you the unique absolute path to the file. It's worth noting that there can be a huge number of absolute paths that point to the same file, but only one canonical path.


2 comments :

Anonymous said...

Does canonical path have something related with symlinks under both Windows and Unix-like?

Anonymous said...

Any path which is starting with root component e.g. / in UNIX and \ in Windows are known as absolute path. The root component totally depends upon operating system e.g. Linux, Mac OS X or Windows.

While, any path which doesn't start with root but from any folder is known as relative path with respect to current folder e.g.

temp/storage is relative to current folder.

Post a Comment