了解java.nio.file.Path.relativize(Path other) [英] Understanding java.nio.file.Path.relativize(Path other)

查看:129
本文介绍了了解java.nio.file.Path.relativize(Path other)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让自己熟悉java.nio.file.Path.relativize()无济于事。

I am trying to familiarize myself with java.nio.file.Path.relativize() to no avail.

我已经阅读了javadocs,我看过例子。但是,我仍然无法理解以下示例(我使用Linux,向窗口用户道歉):

I have read the javadocs, and I have seen examples. However, I still cannot get my head around the following example(I use Linux, apologies to window users):

程序的工作目录是:/ home / userspace / workspace / java8。

Working directory for program is: /home/userspace/workspace/java8.

有两个文件:/home/userspace/workspace/java8/zoo.txt和/home/userspace/temp/delete/dictionary.txt

With two files: /home/userspace/workspace/java8/zoo.txt and /home/userspace/temp/delete/dictionary.txt

以下程序调用Path.relativize():

The following program calls Path.relativize():

package certExam.java8.ch9NIO.paths;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Relativize 
{
    public static void main(String[] args) 
    {
        Path relativePathToZoo = Paths.get("zoo.txt");
        Path relativePathToDictionary = Paths.get("../../temp/delete/dictionary.txt");
        System.out.println("relativePathToZoo.relativize(relativePathToDictionary): "+relativePathToZoo.relativize(relativePathToDictionary));
        System.out.println("relativePathToZoo.relativize(relativePathToDictionary).toAbsolutePath(): "+relativePathToZoo.relativize(relativePathToDictionary).toAbsolutePath());
        System.out.println("relativePathToZoo.relativize(relativePathToDictionary).toAbsolutePath().normalize(): "+relativePathToZoo.relativize(relativePathToDictionary).toAbsolutePath().normalize());
        System.out.println("relativePathToDictionary.relativize(relativePathToZoo): "+relativePathToDictionary.relativize(relativePathToZoo));
        System.out.println("relativePathToDictionary.relativize(relativePathToZoo).toAbsolutePath().normalize(): "+relativePathToDictionary.relativize(relativePathToZoo).toAbsolutePath().normalize());
        System.out.println();
    }
}

输出为:

relativePathToZoo.relativize(relativePathToDictionary): ../../../temp/delete/dictionary.txt 
    relativePathToZoo.relativize(relativePathToDictionary).toAbsolutePath(): /home/userspace/workspace/java8/../../../temp/delete/dictionary.txt 
    relativePathToZoo.relativize(relativePathToDictionary).toAbsolutePath().normalize(): /home/temp/delete/dictionary.txt 
    relativePathToDictionary.relativize(relativePathToZoo): ../../../../../zoo.txt 
    relativePathToDictionary.relativize(relativePathToZoo).toAbsolutePath().normalize(): /zoo.txt

我的问题,我无法理解的是:为什么relativePathToDictionary.relativize(relativePathToZoo)输出../../../../../ zoo.txt?

My question, the bit I cannot understand is: Why does relativePathToDictionary.relativize(relativePathToZoo) output ../../../../../zoo.txt?

当标准化时,它会让你认为zoo.txt存在于根目录中。

When normalized, it would make you think that zoo.txt lives in the root directory.

relativize()如何解决这么深的路径?我知道relativize()与当前工作目录相关,因此它将 .. 添加到每个路径。但我无法理解,它如何解决了与fonts.txt相关的zoo.txt路径。

How does relativize() work out such a deep path? I understand that relativize() works in relation to the current working directory, so it adds .. to every path. But I am cannot understand, how it worked out the path to zoo.txt in relation to dictionary.txt.

提前致谢,

Lucas

推荐答案

首先,当前的工作目录完全无关紧要。我甚至可以在Windows下重现您的问题,我的系统上没有任何这些文件和目录,唯一的区别是使用 \\ 而不是 /

First of all, the current working directory is completely irrelevant. I could reproduce your problem even under Windows, not having any of these files and directories on my system, the only difference being the use of \\ instead of /.

应该怎样做?如果你有一个像 foo bar baz 这样的路径并要求重新激活 foo bar hello ,你将获得 ..你好这是路径,相对于 foo bar baz 来到 foo bar hello ,即 Paths.get(foo,bar,baz)。resolve(Paths.get(..,hello))。normalize() 产生与 Paths.get(foo,bar,hello)相同的路径,无论任何真正的文件系统结构如何。

What should relativize do? If you have a path like foo bar baz and ask for relativizing foo bar hello, you’ll get .. hello as that’s the path, relative to foo bar baz to get to foo bar hello, i.e Paths.get("foo", "bar", "baz").resolve(Paths.get("..", "hello")).normalize() produces the same path as Paths.get("foo", "bar", "hello"), regardless of any real file system structure.

现在你遇到了这个bug JDK-6925169 ,用户 Berger 在评论中的建议。 路径实现不处理 .. 组件正确地在中重新激活,但是将它们视为任何其他路径组件。

Now you ran into the bug JDK-6925169, as suggested by the user Berger in a comment. The Path implementation does not handle . and .. components correctly in relativize, but treats them like any other path component.

所以你是否使用 Paths.get(..,..,temp,delete,dictionary.txt) Paths.get(a ,b,c,d,e),它没有区别,在任何一种情况下,实现都将它视为五个不匹配的路径组件,必须将其删除才能解析到 Paths.get(zoo.txt)。这适用于Windows和Linux。您可以使用以下与平台无关的代码进行验证:

So whether you use Paths.get("..", "..", "temp", "delete", "dictionary.txt") or Paths.get("a", "b", "c", "d", "e"), it makes no difference, in either case, the implementation treats it as five nonmatching path components that have to be removed to resolve to Paths.get("zoo.txt"). This applies to both, Windows and Linux. You may verify it with the following platform-independent code:

Path relative = Paths.get("zoo.txt");
Path base1 = Paths.get("..", "..", "temp", "delete", "dictionary.txt");
Path base2 = Paths.get("a",  "b",  "c",    "d",      "e");

Path relativized1 = base1.relativize(relative);
System.out.println("relativized1: "+relativized1);
Path relativized2 = base2.relativize(relative);
System.out.println("relativized2: "+relativized2);

Path resolved1 = base1.resolve(relativized1).normalize();
System.out.println("resolved1="+resolved1);
Path resolved2 = base2.resolve(relativized2).normalize();
System.out.println("resolved2="+resolved2);

由于重新关联错误地将所有组件视为相同,相对化路径是相同的,但由于规范化操作 处理 .. 路径组件,第一个已解决的路径将显示问题,而第二个解析为预期的 zoo.txt

Since relatize incorrectly treats all component the same, the relativized paths are the same, but since the normalize operation does handle the .. path components, the first resolved path will exhibit the problem whereas the second resolves to the expected zoo.txt.

理解这一点可能很重要,所有路径组件(包括 dictionary.txt )都被视为目录。 relativize 的文档没有明确提及,但您可以从记录的关系派生到 resolve ,其文档说 ...此方法将此路径视为目录

It might be important for the understanding, that all path components, including dictionary.txt, are treated like directories. The documentation of relativize doesn’t mention that explicitly, but you can derive it from the documented relationship to resolve, whose documentation says "… this method considers this path to be a directory".

这篇关于了解java.nio.file.Path.relativize(Path other)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆