Java如何在新的File()中parsing相对path?

我想了解Java在创buildFile对象时parsing相对path的方式。

使用的操作系统:Windows

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

 @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将把path提供为绝对path,并在path不存在时返回一个错误。 所以这是有道理的。

当我更新上面的代码使用相对path:

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

它创build一个新文件并提供下面的输出:

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

在这种情况下,我的假设是,即使提供的path不存在,因为path中包含“/../”,java会将其视为相对path,并在user.dir创build该文件。 所以这也是有道理的。

但是如果我更新相对path如下:

  @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"被视为相对path,并在"user.dir"创build文件,但"test/../../test.txt"返回错误? 它在哪里试图创buildpath"test/../../test.txt"
  2. 当找不到指定的相对path时,该文件似乎是在user.dir创build的。 所以,在我看来,以下两种情况是一样的:

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

那么是否有真实世界的情况下,会使用场景1而不是场景2?

我想我错过了一些明显的东西,或者从根本上误解了相对path。 我经历了文件的Java文档,我无法find解释。 关于相对path,在Stack Overflow中有相当多的问题,但是我查找的是针对特定场景的,而不是完全关于如何parsing相对path。

如果有人能解释我是如何工作的,或者指出一些相关的链接,那将是非常棒的。

有一个working directory的概念。
这个目录由a表示. (点)。
在相对path中,其他的都是相对的。

简单的说. (工作目录)是你运行程序的地方。
在某些情况下,工作目录可以改变,但一般情况下是这样
点代表什么。 我认为这是C:\JavaForTesters\在你的情况。

所以test\..\test.txt是指:在子目录下test
在我的工作目录中,然后是一级,然后是
文件test.txt 。 这与test.txt基本相同。

更多细节请点击这里。

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

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

当你的path以根目录开始时,例如C:\在windows中,或者在Unix中,或者在java资源path中,它被认为是绝对path。 一切都是相对的,所以

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

getAbsolutePathgetCanonicalPath之间的主要区别是第一个连接一个父path和一个子path,所以它可能包含点: ...getCanonicalPath将始终返回特定文件的相同path。

注意: File.equals使用path的抽象forms(getAbsolutePath)来比较文件,所以这意味着两个File对象可能不相同, File不安全,不适合在MapSet集合中使用。

工作目录是几乎所有操作系统和程序语言等的通用概念。它是程序运行的目录。 这通常(但并不总是,有办法改变它)应用程序所在的目录。

相对path是没有驱动器说明符的path。 所以在Linux中,他们不是以/开头的,在Windows中他们不以C:\开头,等等。这些总是从你的工作目录开始。

绝对path是以驱动器(或networkingpath的机器)说明符开始的path。 他们总是从开车的那一刻开始。

在Windows和Netbeans中,您可以将相对path设置为:

  new FileReader("src\\PACKAGE_NAME\\FILENAME"); 

在Linux和Netbeans上,您可以将相对path设置为:

  new FileReader("src/PACKAGE_NAME/FILENAME"); 

如果你在Source Packages里面有你的代码,我不知道它是否与eclipse或其他IDE相同

只涉及到这个问题,但是试着把头围绕在这个问题上。 如此不直观:

 import java.nio.file.*; class Main { public static void main(String[] args) { Path p1 = Paths.get("/personal/./photos/./readme.txt"); Path p2 = Paths.get("/personal/index.html"); Path p3 = p1.relativize(p2); System.out.println(p3); //prints ../../../../index.html !! } }