【问题标题】:How to handle ~ in file paths如何在文件路径中处理 ~
【发布时间】:2018-10-01 23:08:51
【问题描述】:

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

我的问题是有没有办法让 Java 自动解析这种类型的路径?还是我需要扫描~ 运算符的文件路径?

似乎这种类型的功能应该融入File 对象。但好像不是。

【问题讨论】:

  • 您的实用程序适用于哪些操作系统?

标签: java


【解决方案1】:

一个简单的path = path.replaceFirst("^~", System.getProperty("user.home")); 从用户那里获得(在生成File 之前)应该足以在大多数情况下工作 - 因为波浪号只有在它是第一个时才会扩展到主目录路径的目录部分中的字符。

【讨论】:

  • 大多数(全部?)shell 只会在参数 ~ 开头时执行替换。例如,路径 /a/~/c/d.txt 将被解释为 bash 所写的完全一样。
  • @andrzej 那么 petr 的解决方案更好,但我的解决方案更紧凑
  • 请注意,这实际上并不总是有效。 “~otheruser/Documents”也是一个有效的主目录;但是,不是针对“user.home”,而是针对其他用户的“user.home”。此外,如果波浪号是路径目录部分中的第一个字符,它只会扩展为主目录。虽然非常规,但“a~”是一个与主目录无关的有效文件。
  • 有很多 foo.bar~ 文件被文本编辑器存储为备份,您可能不应该尝试更改其名称。
  • @Mehrdad 现在只替换字符串中的第一个字符
【解决方案2】:

这是特定于 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);
...

【讨论】:

  • 不应该是System.getProperty("user.home") + path.substring(2);
  • 不是真的,因为这会删除分隔符,该分隔符通常不存在于 user.home 的值中,并且是正确形成路径所必需的
【解决方案3】:

正如 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;
}

【讨论】:

  • 由于依赖于ls,所以Dave M提供的expandPath方法只有在路径存在的情况下才有效。
  • +1 为此启动一个新进程似乎是一个巨大的矫枉过正,但这可能是唯一“正确”的方式。
【解决方案4】:

一个相当简化的答案,适用于其中包含实际 ~ 字符的路径:

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

【讨论】:

  • 这与@ratchet 的回答有同样的缺陷:~foo 将被/home/yournamefoo 取代而不是/home/foo
【解决方案5】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多