【发布时间】: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。