Java 如何解析 new File() 中的相对路径?

2022-08-31 19:38:58

我试图理解Java在创建对象时解析相对路径的方式。File

使用的操作系统:窗口

对于下面的代码段,我得到了一个,因为它找不到路径:IOException

@Test
public void testPathConversion() {
        File f = new File("test/test.txt");
        try {
            f.createNewFile();
            System.out.println(f.getPath());
            System.out.println(f.getAbsolutePath());    
            System.out.println(f.getCanonicalPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
}

我的理解是,Java将提供的路径视为绝对路径,并在路径不存在时返回错误。所以这是有道理的。

当我更新上面的代码以使用相对路径时:

@Test
    public void testPathConversion() {
        File f = new File("test/../test.txt");
        try {
            f.createNewFile();
            System.out.println(f.getPath());
            System.out.println(f.getAbsolutePath());    
            System.out.println(f.getCanonicalPath());
        } catch (Exception e) {
            e.printStackTrace();
        }    
    }

它将创建一个新文件并提供以下输出:

test\..\test.txt
C:\JavaForTesters\test\..\test.txt
C:\JavaForTesters\test.txt

在这种情况下,我的假设是,即使提供的路径不存在,因为路径包含“/../“,java 将此路径视为相对路径,并在 .所以这也是有道理的。user.dir

但是如果我更新相对路径,如下所示:

   @Test
    public void testPathConversion() {
        File f = new File("test/../../test.txt");
        try {
            f.createNewFile();
            System.out.println(f.getPath());
            System.out.println(f.getAbsolutePath());
            System.out.println(f.getCanonicalPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

然后我得到IOException:访问被拒绝。

我的问题是:

  1. 为什么被视为相对路径并在 中创建文件但返回错误?它在哪里尝试为路径创建文件?"test/../test.txt""user.dir""test/../../test.txt""test/../../test.txt"
  2. 如果未找到指定的相对路径,则似乎已在 中创建该文件。因此,在我看来,以下两种情况可以做同样的事情:user.dir

    //scenario 1
    File f = new File("test/../test.txt");
    f.createNewFile();
    
    //scenario 2
    File f = new File("test.txt");
    f.createNewFile();
    

那么,在现实世界中,是否有人会使用场景1而不是场景2呢?

我想我在这里错过了一些明显的东西,或者从根本上误解了相对路径。我浏览了File的Java文档,但我无法找到对此的解释。Stack Overflow中发布了很多关于相对路径的问题,但我查找的问题是针对特定场景的,而不是关于如何解决相对路径的。

如果有人能解释一下这是如何工作的或指向一些相关链接,那就太好了?


答案 1

有一个 .
此目录由一个(点)表示。
在相对路径中,其他一切都是相对于它的。working directory.

简单地说(工作目录)是你运行程序的地方。
在某些情况下,可以更改工作目录,但通常这就是点
所代表的内容。我认为这是在你的情况下。.C:\JavaForTesters\

所以意味着:我的工作目录中
的子目录,然后向上一级,然后是
文件。这与 只是 基本相同。test\..\test.txttesttest.txttest.txt

有关更多详细信息,请查看此处。

http://docs.oracle.com/javase/7/docs/api/java/io/File.html

http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html


答案 2

当您的路径以根目录开始时,即 在Windows或Unix或Java资源路径中,它被认为是绝对路径。其他一切都是相对的,所以C:\/

new File("test.txt") is the same as new File("./test.txt")

new File("test/../test.txt") is the same as new File("./test/../test.txt")

和 之间的主要区别在于,第一个连接父路径和子路径,因此它可能包含点:或 。 将始终为特定文件返回相同的路径。getAbsolutePathgetCanonicalPath...getCanonicalPath

注意:使用路径 () 的抽象形式来比较文件,因此这意味着相同的两个对象可能不相等,并且在集合中使用 s 是不安全的,例如 或 。File.equalsgetAbsolutePathFileFileMapSet