File / FileInputStream相对路径奇怪的行为

时间:2013-09-19 22:24:38

标签: java file

我将java属性user.dir设置为 / home / alex / projects / poltava / rpgu / workingdir 。我还在上面的文件夹中记录了 q.txt

以下是代码段及其返回值(在=之后):

System.getProperty("user.dir") = /home/alex/projects/poltava/rpgu/workingdir
new File(".").getAbsolutePath() = /home/alex/projects/poltava/rpgu/workingdir/.
new File(".").exists() = true
new File("q.txt").getAbsolutePath() = /home/alex/projects/poltava/rpgu/workingdir/q.txt
new File("q.txt").exists() = false
new File(new File("q.txt").getAbsolutePath()).exists() = true
new FileInputStream("q.txt") = threw FileNotFoundException

因此,您可以看到文件在文件系统中确实存在。当我试图用绝对路径获得它时,一切都很好。当我尝试用相对路径获取它时,它会失败。

我对相对路径有什么不对?

编辑:

演示此问题的小应用程序:

import java.io.File;

public class Test {
    public static void main(String[] args) {
        System.setProperty("user.dir", "/home/alex/projects/poltava/rpgu/workingdir");
        System.out.println(System.getProperty("user.dir"));
        System.out.println(new File("q.txt").exists());
        System.out.println(new File("q.txt").isFile());
        System.out.println(new File("q.txt").canRead());

        System.out.println(new File("q.txt").getAbsolutePath());
        System.out.println(new File(new File("q.txt").getAbsolutePath()).exists());
        System.out.println(new File(new File("q.txt").getAbsolutePath()).isFile());
        System.out.println(new File(new File("q.txt").getAbsolutePath()).canRead());

        try {
            new FileInputStream("q.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出:

/home/alex/projects/poltava/rpgu/workingdir
false
false
false
/home/alex/projects/poltava/rpgu/workingdir/q.txt
true
true
true
java.io.FileNotFoundException: q.txt (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:146)
    at java.io.FileInputStream.<init>(FileInputStream.java:101)
    at Test.main(Test.java:24)

已编辑2:

我还尝试了另一个简单的例子:

File f = new File("q1.txt");
System.out.println(f.createNewFile());
System.out.println(f.getPath());
System.out.println(f.getAbsolutePath());

输出:

true
q1.txt
/home/alex/projects/poltava/rpgu/workingdir/q1.txt

在结果文件中创建在我启动应用程序的目录中。不在user.dir目录中。 getAbsolutePath()返回错误的文件路径。

2 个答案:

答案 0 :(得分:1)

我认为阅读javadoc for File会更好。

帮助您入门的一些解释:

对于您正在使用的构造函数:

  

公共文件(字符串路径名)

     

通过转换给定的路径名​​字符串来创建新的File实例   成为一个抽象的路径名。如果给定的字符串是空字符串,   然后结果是空的抽象路径名。

基本上你得到的是一个File实例,其抽象路径名为“q.txt”。

对此进行getAbsolutePath()会发生什么。再次来自javadoc:

  

<强> public String getAbsolutePath()

     

返回此抽象路径名的绝对路径名字符串。    如果此抽象路径名已经是绝对路径名,则为路径名    简单地返回字符串,就好像getPath()方法一样。如果这    abstract pathname是空的抽象路径名,然后是路径名    当前用户目录的字符串,由系统命名    属性user.dir,返回。否则,此路径名将被解析    一种依赖于系统的方式。在UNIX系统上,创建相对路径名    绝对通过解析当前用户目录。

     

在Microsoft Windows系统上,相对路径名是绝对的    通过将其解析为名为的驱动器的当前目录    路径名,如果有的话;如果没有,它将被解决当前的问题    用户目录。

你看到发生了什么吗?特别是关于user.dir

更多提示:

现在创建另一个变量,例如

File newFile = new File(System.getProperty("user.dir"), "q.txt")

newFile上尝试相同的操作。尝试使用前一个版本的getParent()以及此版本的{{1}}。你会看到差异。

我希望这有助于为您澄清几点:)

答案 1 :(得分:0)

这是因为File(String str)将调用normalize,但是getAbsolutePath也会调用resolve,这里有user.dir被使用的地方。请看下面的例子。

System.setProperty("user.dir", "/home/alex/projects/poltava/rpgu/workingdir");

File fString = new File("Test.txt");
File fAbsolutePath = new File(fString.getAbsolutePath());

System.out.println(System.getProperty("user.dir"));
System.out.println(fString.getPath());
System.out.println(fAbsolutePath.getPath());

这是输出:

/home/alex/projects/poltava/rpgu/workingdir
Test.txt
\home\alex\projects\poltava\rpgu\workingdir\Test.txt

你可以在这里看到src代码: 新文件(String str) http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/io/File.java#File.%3Cinit%3E%28java.io.File%2Cjava.lang.String%29

getAbsolutePath: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/io/File.java#File.getAbsolutePath%28%29