【问题标题】:What is the best way to ignore a leading slash when resolving a java.nio.files.Path解析 java.nio.files.Path 时忽略前导斜杠的最佳方法是什么
【发布时间】:2020-03-06 14:15:35
【问题描述】:

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

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

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

  • 父目录下的子文件/目录,无论子文件是否以/开头。

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

  • 父目录下的子文件/目录
  • child 作为根(如果它以/ 开头)

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

在使用 Path 时恢复旧 (File) 行为的最佳/最干净的方法是什么?


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();
  }
}

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

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

【问题讨论】:

  • absolute.getRoot().relativize(absolute)) 是本例中删除根组件的一种方式。
  • 不是我想要的(结果不再包含父级,并且当/ 不存在时,可能会失败,因为getRoot()null)。我编辑了问题以使期望更加清晰。
  • 就在您问题中的方法名称上。 “resolveSafely”不是一个好名字,因为它更像是 concat 而不是 resolve。 Path 定义的解析方法做正确的事,2-arg File 构造更像是 concat。

标签: java nio filepath


【解决方案1】:

我能找到的最好方法是:

    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 类可能会在未来的版本中被弃用。

【讨论】:

  • 我没有意识到Paths.get 的行为与Path.resolve 的行为不同。这确实是我一直在寻找的。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 2019-09-16
  • 1970-01-01
  • 1970-01-01
  • 2018-06-02
相关资源
最近更新 更多