Joining paths in Java

By | July 8, 2019

Question

In Python I can join two paths with os.path.join:

os.path.join("foo", "bar") # => "foo/bar"

I’m trying to achive the same in Java, without worrying if the OS is Unix, Solaris or Windows:

public static void main(String[] args) {
    Path currentRelativePath = Paths.get("");
    String current_dir = currentRelativePath.toAbsolutePath().toString();
    String filename = "data/foo.txt";
    Path filepath = currentRelativePath.resolve(filename);

    // "data/foo.txt"
    System.out.println(filepath);

}

I was expecting that Path.resolve( ) would join my current directory /home/user/test with data/foo.txt making /home/user/test/data/foo.txt.
What am I getting wrong?

Solution

Even though the original solution for getting the current directory using the empty String works. But is recommended to use the user.dir property for current directory and user.home for home directory.

Path currentPath = Paths.get(System.getProperty("user.dir"));
Path filePath = Paths.get(currentPath.toString(), "data", "foo.txt");
System.out.println(filePath.toString());

output:

/Users/user/coding/data/foo.txt

From Java Path class Documentation:

A Path is considered to be an empty path if it consists solely of one name element that is empty. Accessing a file using an empty path is equivalent to accessing the default directory of the file system.

Why Paths.get("").toAbsolutePath() works

When an empty string is passed to the Paths.get(""), the returned Path object contains empty path. But when we call Path.toAbsolutePath(), it checks whether path length is greater than zero, otherwise it uses user.dir system property and return the current path.

Here is the code for Unix file system implementation: UnixPath.toAbsolutePath()

Basically you need to create the Path instance again once you resolve the current directory path.

Also I would suggest using File.separatorChar for platform independent code.

Path currentRelativePath = Paths.get("");
Path currentDir = currentRelativePath.toAbsolutePath(); // <-- Get the Path and use resolve on it.
String filename = "data" + File.separatorChar + "foo.txt";
Path filepath = currentDir.resolve(filename);

// "data/foo.txt"
System.out.println(filepath);

Output:

/Users/user/coding/data/foo.txt

Rate this post

Leave a Reply

Your email address will not be published. Required fields are marked *