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 java.io.File;
import com.google.common.base.Joiner;
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 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.
String home = System.getProperty("user.home");
// does not work on *nix
// works on Windows
boolean directoryExists = new java.io.File(home + "\\my\\app\\dir").exists()