How Do I Make Cross-Platform File Paths in Java?
— java, code, quality — 1 min read
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.
1String home = System.getProperty("user.home");
1// inserts correct file path separator on *nix and Windows2// works on *nix3// works on Windows4java.nio.file.Path path = java.nio.file.Paths.get(home, "my", "app", "dir")5boolean 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.
1import java.io.File;2import com.google.common.base.Joiner;3import org.apache.commons.lang3.StringUtils;
1String home = System.getProperty("user.home");23// works on *nix4String path = home + File.separator + "my" + File.separator + "app" + File.separator + "dir";56// or if you have Google Guava7path = Joiner.on(File.separator).join(home, "my", "app", "dir");89// or if you have Apache Commons10java.util.List pathParts = java.util.Arrays.asList(home, "my", "app", "dir");11path = StringUtils.join(pathParts, File.separator);1213boolean 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.
1String home = System.getProperty("user.home");
1// works on *nix2// works on Windows3boolean directoryExists = new java.io.File(home + "/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.
1String home = System.getProperty("user.home");
1// does not work on *nix2// works on Windows3boolean directoryExists = new java.io.File(home + "\\my\\app\\dir").exists()