如何在文件路径中处理〜

Kar*_*ran 51 java

我正在编写一个简单的命令行Java实用程序.我希望用户能够使用~运算符传递相对于其主目录的文件路径.所以像~/Documents/...

我的问题是有没有办法让Java自动解决这种类型的路径?或者我是否需要扫描~运营商的文件路径?

看起来这种类型的功能应该被烘焙到File对象中.但似乎并非如此.

rat*_*eak 67

path = path.replaceFirst("^~", System.getProperty("user.home"));从用户那里得到一个简单的东西(在制作File它之前)应该足以在大多数情况下工作 - 因为如果它是路径的目录部分中的第一个字符,则只扩展到主目录.

  • 请注意,这确实不会一直有效."~otheruser/Documents"也是一个有效的主目录; 但是,不是"user.home",对于其他用户的"user.home".此外,如果波形符是路径的目录部分中的第一个字符,则波形符仅扩展到主目录.虽然非常规,"a~"是一个与主目录无关的有效文件. (20认同)
  • 大多数(全部?)shell只会在argumentmetn*以*`~`开头时执行替换.例如,路径`/ a /〜/ c/d.txt`将完全解释为由bash编写. (6认同)
  • 文本编辑器存储了很多`foo.bar~`文件作为备份,您可能不应该尝试更改其名称. (3认同)
  • @Mehrdad现在只替换字符串中的第一个字符 (2认同)

Pet*_*lka 30

这是特定于shell的扩展,因此您需要在行的开头替换它(如果存在):

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);
...
Run Code Online (Sandbox Code Playgroud)

  • 不应该是`System.getProperty("user.home")+ path.substring(2);` (4认同)

小智 10

正如Edwin Buck在评论中指出的另一个答案,~otheruser/Documents也应该正确扩展.这是一个对我有用的功能:

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 由于它依赖于ls,Dave M提供的expandPath方法仅在路径存在时才有效. (2认同)
  • +1为此启动一个新进程似乎是一个巨大的矫枉过正,但它可能是唯一"正确"的方式. (2认同)

小智 5

一个相当简化的答案,适用于其中带有实际〜字符的路径:

String path = "~/Documents";
path.replaceFirst("^~", System.getProperty("user.home"));
Run Code Online (Sandbox Code Playgroud)

  • 这与@ratchet的回答有相同的缺陷:~~ foo将被`/ home / yournamefoo`代替`/ home / foo`。 (3认同)

小智 5

当用户主目录包含“\”或其他特殊字符时,前面提到的解决方案不会按预期运行。这对我有用:

path = path.replaceFirst("^~", Matcher.quoteReplacement(System.getProperty("user.home")));
Run Code Online (Sandbox Code Playgroud)