How Do I Make Cross-Platform File Paths in Java?

June 01, 2014

Let’s assume our Java application needs to write to a file at the following locations -

  • ~/my/app/dir on *nix
  • ~\my\app\dir on Windows

Despite Java’s “write once, run anywhere” original sales pitch, many Java projects are developed, tested, and deployed exclusively on one platform. Often someone discovers they’d have a wider market if they sold their app to *nix and Windows users. Depending on details like how file paths have been constructed, going cross-platform can either be no big deal, or take days of expensive development time.

Before writing to a directory, we’ll check if that directory exists. Here are some common ways to do just that.

1.7+ JDK Paths - OK

If you’re on Java 7 or later, you’ve got access to the java.nio.file.Paths and java.nio.file.Files classes.

String home = System.getProperty("user.home");

// inserts correct file path separator on *nix and Windows
// works on *nix
// works on Windows
java.nio.file.Path path = java.nio.file.Paths.get(home, "my", "app", "dir")
boolean directoryExists = java.nio.file.Files.exists(path);

Pre-1.7 JDK Paths - OK

Prior to Java 7 we didn’t have the nice helper classes above. Instead we have to concatenate a string, which is made easier if you’re using a library like Apache Commons Lang or Google’s Guava.

import org.apache.commons.lang3.StringUtils;

String home = System.getProperty("user.home");

// works on *nix
String path = home + File.separator + "my" + File.separator + "app" + File.separator + "dir";

// or if you have Google Guava
path = Joiner.on(File.separator).join(home, "my", "app", "dir");

// or if you have Apache Commons
java.util.List pathParts = java.util.Arrays.asList(home, "my", "app", "dir");
path = StringUtils.join(pathParts, File.separator);

boolean directoryExists = new File(path).exists();

Hardcoded Unix Paths - OK

I was surprised to find out that Unix path characters seem to just work (thanks to StackOverflow user EJP’s experience). This leaves me feeling a little uneasy, especially if your goal is to deploy to multiple platforms and implementations of the JDK.

String home = System.getProperty("user.home");

// works on *nix
// works on Windows
boolean directoryExists = new + "/my/app/dir").exists()

Hardcoded Windows Paths - NO

If the one platform you’re developing, testing, and deploying on is Windows, this is probably a familiar sight. Unfortunately, this is the code that will require a bunch of String changes and lots of subsequent testing.

String home = System.getProperty("user.home");

// does not work on *nix
// works on Windows
boolean directoryExists = new + "\\my\\app\\dir").exists()

Profile picture

Written by @sghill, who works on build, automated change, and continuous integration systems.