How to handle ~ in file paths

Java

Java Problem Overview


I'm writing a simple command line Java utility. I would like the user to be able to pass in a file path relative to their home directory using the ~ operator. So something like ~/Documents/...

My question is is there a way to make Java resolve this type of path automatically? Or do I need to scan the file path for the ~ operator?

It seems like this type of functionality should be baked into the File object. But it doesn't seem to be.

Java Solutions


Solution 1 - Java

A simple path = path.replaceFirst("^~", System.getProperty("user.home")); when it is gotten from the user (before making a File out of it) should be enough to work in most cases - because the tilde is only expanded to a home directory if it is the first character in a directory section of a path.

Solution 2 - Java

This is shell-specific expansion, so you need to replace it at the beginning of the line, if present:

String path = "~/xyz";
...
if (path.startsWith("~" + File.separator)) {
    path = System.getProperty("user.home") + path.substring(1);
} else if (path.startsWith("~")) {
    // here you can implement reading homedir of other users if you care
    throw new UnsupportedOperationException("Home dir expansion not implemented for explicit usernames");
}

File f = new File(path);
...

Solution 3 - Java

As Edwin Buck pointed out in the comment to another answer, ~otheruser/Documents should also expand correctly. Here's a function that worked for me:

public String expandPath(String path) {
    try {
        String command = "ls -d " + path;
        Process shellExec = Runtime.getRuntime().exec(
            new String[]{"bash", "-c", command});

        BufferedReader reader = new BufferedReader(
            new InputStreamReader(shellExec.getInputStream()));
        String expandedPath = reader.readLine();

        // Only return a new value if expansion worked.
        // We're reading from stdin. If there was a problem, it was written
        // to stderr and our result will be null.
        if (expandedPath != null) {
            path = expandedPath;
        }
    } catch (java.io.IOException ex) {
        // Just consider it unexpandable and return original path.
    }

    return path;
}

Solution 4 - Java

A fairly streamlined answer that works with paths with actual ~ characters in them:

String path = "~/Documents";
path.replaceFirst("^~", System.getProperty("user.home"));

Solution 5 - Java

Previously mentioned solutions do not behave as expected when user home contains '' or other special chars. This works for me:

path = path.replaceFirst("^~", Matcher.quoteReplacement(System.getProperty("user.home")));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKarthik RamachandranView Question on Stackoverflow
Solution 1 - Javaratchet freakView Answer on Stackoverflow
Solution 2 - JavaPetr KozelkaView Answer on Stackoverflow
Solution 3 - JavaDave MView Answer on Stackoverflow
Solution 4 - JavaenrichedView Answer on Stackoverflow
Solution 5 - JavaMatthiasView Answer on Stackoverflow