解析 java.nio.files.Path 时忽略前导斜杠的最佳方法是什么

What is the best way to ignore a leading slash when resolving a java.nio.files.Path

我正在尝试使用 java.io.File 重构一些旧代码以使用 java.nio.file.Path 代替。

我被 Path 更好地支持绝对文件路径这一事实所困扰,因为我收到的很多值都有一个前导斜杠 (/),而它们应该代表相对路径。字符串连接更容易,但我试图从 String/File 转移到表示文件路径。

旧的行为是 new File(parent, child) 返回一个新的 File 表示

新的行为是 parent.resolve(child) 返回一个新的 Path 代表

我认为新方法可以使代码更简洁,但是在重构遗留应用程序时它可能会引入细微的错误。

使用 Path 时恢复旧 (File) 行为的 best/cleanest 方法是什么?


import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

class Main {
  public static void main(String[] args) {
    file();
    path();
  }

  public static void file(){
    File root = new File("/root");
    File relative = new File(root, "relative");
    File absolute = new File(root, "/absolute");

    System.out.println("File:");
    System.out.println(relative.getAbsolutePath()); // prints "/root/relative"
    System.out.println(absolute.getAbsolutePath()); // prints "/root/absolute"
    System.out.println();
  }

  public static void path(){
    Path root = Paths.get("/root");
    Path relative = root.resolve("relative");
    Path absolute = root.resolve("/absolute");

    System.out.println("Path:");
    System.out.println(relative.toAbsolutePath()); // prints "/root/relative"
    System.out.println(absolute.toAbsolutePath()); // prints "/absolute" but should print "/root/absolute"
    System.out.println();
  }
}

基本上我想要的是一个采用父路径的方法,以及一个 returns 我是父+子路径的子字符串,无论子是否有前导 /.
像这样,但没有依赖于我知道配置将使用 /(而不是 \)的字符串操作:

private static Path resolveSafely(Path parent, String child) {
    child = child.startsWith("/")
            ? child.substring(1)
            : child;
    parent.resolve(child);
}

我能找到的最好方法是:

    Path root = Paths.get("/root");
    Path relative = root.resolve("relative");
    Path absolute = Paths.get(root.toString(), "/absolute");

    System.out.println("Path:");
    System.out.println(relative.toAbsolutePath()); // prints "/root/relative"
    System.out.println(absolute.toAbsolutePath()); // prints "/root/absolute"
    System.out.println();

希望这就是您所需要的。

编辑:自 Java 11 起,Path.of() 可用并且是获取 Path 对象而不是 Paths.get() 的推荐方式。 Check javadoc 还指出 Paths class 可能会在未来的版本中弃用。