java.nio.file.Path类中的resolve()和relativize()方法应该在哪些情况下使用?

30
Path p1 = Paths.get("/Users/jack/Documents/text1.txt");
Path p2 = Paths.get("/Users/jack/text2.txt");
Path result1 = p1.resolve(p2);
Path result2 = p1.relativize(p2);

System.out.println("result1: "+result1);
System.out.println("result2: "+result2);

输出

result1: /Users/jack/text2.txt
result2: ../../text2.txt

我不太理解resolve()relativize()的工作原理。

result1result2的实际用途是什么?

5个回答

51

我不明白 resolve() 和 relativize() 方法是如何工作的?

Path resolve(Path) 方法将给定的路径与当前路径进行解析。
Path relativize(Path) 方法构造给定路径相对于当前路径的相对路径。
这些方法是相反的操作。


Path resolve(Path other)

在通常使用 resolve() 的情况下,您想要返回一个新的 Path 对象,其中您将连接此 Path 对象和作为参数的相对路径,例如:

Path p1 = Paths.get("/Users/jack");
Path p2 = Paths.get("text1.txt");
Path result1 = p1.resolve(p2);

这里result1将是p1p2的路径拼接,即:/Users/jack/text1.txt

在您的示例中,传递给该方法的参数不是相对路径Path,而是绝对路径:

Path p1 = Paths.get("/Users/jack/Documents/text1.txt");
Path p2 = Paths.get("/Users/jack/text2.txt");
Path result1 = p1.resolve(p2); 

如果第二个参数是绝对路径,将一个Path附加到另一个Path就没有意义。
因此,文档中认为在这种情况下,该参数将作为resolve()方法的结果返回:

如果其他参数是绝对路径,则此方法会直接返回其他路径。

Path relativize(Path other)

文档更具体地说明:

此方法尝试构造相对路径,使得与给定路径解析后定位的文件与this路径相同。

这意味着返回的Path是相对于this PathPath参数的相对路径。

例如,如果this路径是"/a/b",给定的路径是"/a/b/c/d",则生成的相对路径将是"c/d"

我们将使用您提供的示例进行检查:

Path p1 = Paths.get("/Users/jack/Documents/text1.txt");
Path p2 = Paths.get("/Users/jack/text2.txt");
Path result2 = p1.relativize(p2);   
// result2= ../../text2.txt

期望的结果是路径 ../../text2.txt,因为对于路径 /Users/jack/Documents/text1.txt 而言,将相对路径 (../../text2.txt) 解析得到的路径与 this 路径定位到同一文件,即给定路径为 /Users/jack/text2.txt

Paths.of("/Users/jack/Documents/text1.txt").resolve("../../text2.txt")

returns -> /Users/jack/text2.txt

5
这应该被标记为正确答案。 - Eric Huang
“Resolve”听起来像一个奇怪的名字来描述路径的连接过程。为什么不使用“join”这个名字呢? - undefined

7

resolve(): 合并两个路径。

relativize(): 从文件系统中的一个位置构造到另一个位置的路径。

输出说明:

result1: /Users/jack/text2.txt: 因为您传递了绝对路径,如果它是绝对路径,resolve() 将原样返回传递的路径。

result2: ../../text2.txt: 要从/Users/jack/Documents/text1.txt"到达/Users/jack/text2.txt,您需要向上移动两个级别,然后只选择`text2.txt`文件。


5

Path::resolve - 将给定路径相对于此路径解析。

如果另一个参数是绝对路径,则该方法无需操作,直接返回另一个参数。

Path p1 = Paths.get("/usr");
Path p2 = Paths.get("/etc");
Path p3 = p1.resolve(p2); // returns /etc

如果"other"是一个空路径,则该方法轻松地返回此路径。
Path p1 = Paths.get("/usr");
Path p2 = Paths.get("");
Path p3 = p1.resolve(p2); // returns /usr

否则,该方法会将此路径视为目录,并将给定路径解析为相对于此路径的路径。
Path p1 = Paths.get("/usr");
Path p2 = Paths.get("local");
Path p3 = p1.resolve(p2); // returns /usr/local

Path::relativize - 构造此路径与给定路径之间的相对路径。

Path p1 = Paths.get("/usr");
Path p2 = Paths.get("/usr/local");
Path p3 = p1.relativize(p2); // returns local

这也意味着

Path p1 = Paths.get("/usr");
Path p2 = Paths.get("/usr/../usr/local");
Path p3 = p1.relativize(p2); // returns local

但如果这两个路径相同,则返回空路径

Path p1 = Paths.get("/usr");
Path p2 = Paths.get("/usr/../usr");
Path p3 = p1.relativize(p2); // returns empty path

4
这些是我的代码库中的代码片段,可以帮助您理解resolve()方法的使用。
private File initUsersText() throws Exception
{
    Path dir = testdir.getPath().toRealPath();
    FS.ensureDirExists(dir.toFile());
    File users = dir.resolve("users.txt").toFile();

    writeUser( users );
    return users;
}


private File initUsersText() throws Exception
{
    Path dir = testdir.getPath().toRealPath();
    FS.ensureDirExists(dir.toFile());
    File users = dir.resolve("users.txt").toFile();

    writeUser( users );
    return users;
}

以下是relativize()方法的使用示例:
public ScopePath pathToClassName(Path file) {
    if (!isValidClass(file))
        return null;

    Path relativePath = root.relativize(root.resolve(file));
    String withoutExtension = removeExtension(relativePath.toString());
    return new ScopePath(withoutExtension.replace(File.separator, "."));
}


private String getRelativePath(Path p) {
    String relativePath = packageDir.relativize(p)
            .toString();

    if (File.separator.equals("\\")) {
        relativePath = relativePath.replace("\\", "/");
    }

    return relativePath;
}

为什么 initUsersText 写了两次? :) - Prid

1
< p > resolve(Path) 是一种通过将现有路径连接到当前路径来创建新路径的方法。 < /p >
Path path1 = Paths.get("/test1/../test2");
Path path2 = Paths.get("test3");
System.out.println(path1.resolve(path2));

结果将是:/test1/../test2/test3 实际上,relativize(Path) 方法用于构建从一个 Path 对象到另一个 Path 对象的相对路径:
Path path1= Paths.get("E:\\test1");
Path path2= Paths.get("E:\\test2\\test3");
System.out.println(path1.relativize(path2));
System.out.println(path2.relativize(path1));

结果将会是:
..\test2\test3  relative path from path1 to path2
..\..\test1     relative path from path2 to path1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接