Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java

1. Overview

The java.io.File class has three methods — getPath()getAbsolutePath() and getCanonicalPath() — to obtain the filesystem path.

In this article, we’ll have a quick look at the differences between them and discuss a use case where you may choose to use one over the others.

2. Method Definitions and Examples

Let’s start by going over the definitions of the three methods, along with examples based on having the following directory structure present in the user’s home directory:

|-- maixuanviet
    |-- maixuanviet.txt
    |-- foo
    |   |-- foo-one.txt
    |   \-- foo-two.txt
    \-- bar
        |-- bar-one.txt
        |-- bar-two.txt
        \-- baz
            |-- baz-one.txt
            \-- baz-two.txt

2.1. getPath()

Simply put, getPath() returns the String representation of the file’s abstract pathname. This is essentially the pathname passed to the File constructor.

So, if the File object was created using a relative path, the returned value from getPath() method would also be a relative path.

If we invoke the following code from the {user.home}/maixuanvietdirectory:

File file = new File("foo/foo-one.txt");
String path = file.getPath();

The path variable would have the value:

foo/foo-one.txt  // on Unix systems
foo\foo-one.txt  // on Windows systems

Notice that for the Windows system, the name-separator character has changed from the forward slash(/) character, which was passed to the constructor, to the backslash (\) character. This is because the returned String always uses the platform’s default name-separator character.

2.2. getAbsolutePath()

The getAbsolutePath() method returns the pathname of the file after resolving the path for the current user directory — this is called an absolute pathname. So, for our previous example, file.getAbsolutePath() would return:

/home/username/maixuanviet/foo/foo-one.txt     // on Unix systems
C:\Users\username\maixuanviet\foo\foo-one.txt  // on Windows systems

This method only resolves the current directory for a relative path. Shorthand representations (such as “.” and “..”) are not resolved further. Hence when we execute the following code from the directory {user.home}/maixuanviet:

File file = new File("bar/baz/../bar-one.txt");
String path = file.getAbsolutePath();

The value of the variable path would be:

/home/username/maixuanviet/bar/baz/../bar-one.txt      // on Unix systems
C:\Users\username\maixuanviet\bar\baz\..\bar-one.txt   // on Windows systems

2.3. getCanonicalPath()

The getCanonicalPath() method goes a step further and resolves the absolute pathname as well as the shorthands or redundant names like “.” and “.. as per the directory structure. It also resolves symbolic links on Unix systems and converts the drive letter to a standard case on Windows systems.

So for the previous example, getCanonicalPath() method would return:

/home/username/maixuanviet/bar/bar-one.txt     // on Unix systems
C:\Users\username\maixuanviet\bar\bar-one.txt  // on Windows systems

Let’s take another example. Given current directory as ${user.home}/maixuanviet and File object created using the parameter new File(“bar/baz/./baz-one.txt”), the output for getCanonicalPath() would be:

/home/username/maixuanviet/bar/baz/baz-one.txt     // on Unix systems
C:\Users\username\maixuanviet\bar\baz\baz-one.txt  // on Windows Systems

It’s worth mentioning that a single file on the filesystem can have an infinite number of absolute paths since there’s an infinite number of ways shorthand representations can be used. However, the canonical path will always be unique since all such representations are resolved.

Unlike the last two methods, getCanonicalPath() may throw IOException because it requires filesystem queries.

For example, on Windows systems, if we create a File object with one of the illegal characters, resolving the canonical path will throw an IOException:

new File("*").getCanonicalPath();

3. Use Case

Let’s say we’re writing a method that takes in a File object as a parameter and saves its fully qualified name into a database. We don’t know whether the path is relative or contains shorthands. In this case, we may want to use getCanonicalPath().

However, since getCanonicalPath() reads the filesystem, it comes at a performance cost. If we are sure that there are no redundant names or symbolic links and drive letter case is standardized (if using a Windows OS), then we should prefer using getAbsoultePath().

4. Conclusion

In this quick tutorial, we covered the differences between the three File methods to get filesystem path. We have also shown a use case where one method may be preferred over the other.

Junit test class demonstrating the examples of this article can be found over on GitHub.

Related posts:

Đồng bộ hóa các luồng trong Java
Java Program to Implement Cubic convergence 1/pi Algorithm
Java Program to Implement WeakHashMap API
A Guide to the ViewResolver in Spring MVC
Loại bỏ các phần tử trùng trong một ArrayList như thế nào?
Java Program to Remove the Edges in a Given Cyclic Graph such that its Linear Extension can be Found
Guide to the Java ArrayList
Java Program to Implement RoleUnresolvedList API
Java Program to Implement Double Order Traversal of a Binary Tree
HandlerAdapters in Spring MVC
Java Program to Find Shortest Path Between All Vertices Using Floyd-Warshall’s Algorithm
Deploy a Spring Boot WAR into a Tomcat Server
Hướng dẫn sử dụng Printing Service trong Java
Array to String Conversions
Lớp lồng nhau trong java (Java inner class)
Một số từ khóa trong Java
Guide to the Java TransferQueue
Java Program to Perform Partial Key Search in a K-D Tree
Java Program to Perform Searching Based on Locality of Reference
Java Program to Create a Minimal Set of All Edges Whose Addition will Convert it to a Strongly Conne...
Java Program to Represent Linear Equations in Matrix Form
A Guide to the finalize Method in Java
Giới thiệu HATEOAS
Java Program for Douglas-Peucker Algorithm Implementation
Java Program to Perform the Unique Factorization of a Given Number
Java Program to Implement a Binary Search Algorithm for a Specific Search Sequence
Jackson – Bidirectional Relationships
Join and Split Arrays and Collections in Java
Beans and Dependency Injection
Java Program to Implement Adjacency Matrix
Java Program to Perform Arithmetic Operations on Numbers of Size
Spring 5 Testing with @EnabledIf Annotation