简体   繁体   English

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

[英]File/FileInputStream relative path strange behaviour

I set java property user.dir to /home/alex/projects/poltava/rpgu/workingdir . 我将Java属性user.dir设置为/ home / alex / projects / poltava / rpgu / workingdir Also I have file q.txt inside above folder. 另外我在上面的文件夹中有文件q.txt

Below is the code snippets and their return values (after =): 以下是代码段及其返回值(在=之后):

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

So that as you can see file is realy exists in file system. 如您所见,文件系统中确实存在文件。 When I try to get it with absolute path, everything is well. 当我尝试通过绝对路径获得它时,一切都很好。 When I try to get it with relative path, it fails. 当我尝试使用相对路径获取它时,它失败了。

What do I wrong with relative path? 我相对路径有什么问题?

EDITED: 编辑:

Small application that demonstrates the problem: 演示问题的小型应用程序:

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

Output: 输出:

/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)

EDITED 2: 编辑2:

I also tried another simple example: 我还尝试了另一个简单的示例:

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

An output: 输出:

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

In result file is created in directory from which I launch the application. 结果文件在启动应用程序的目录中创建。 Not in user.dir directory. 不在user.dir目录中。 And getAbsolutePath() returns incorrect file path. 并且getAbsolutePath()返回不正确的文件路径。

I think it would serve you better to read the javadoc for File . 我认为最好阅读Filejavadoc

A little bit of explanation to help you get started: 一点点帮助您入门的解释:

For the constructor that you're using: 对于您使用的构造函数:

public File(String pathname) 公共文件(字符串路径名)

Creates a new File instance by converting the given pathname string into an abstract pathname. 通过将给定的路径名​​字符串转换为抽象路径名来创建新的File实例。 If the given string is the empty string, then the result is the empty abstract pathname. 如果给定的字符串为空字符串,则结果为空的抽象路径名。

So essentially what you get is a File instance, with the abstract pathname " q.txt ". 因此,基本上,您获得的是一个File实例,其抽象路径q.txtq.txt ”。

What happens when you do a getAbsolutePath() on this. 当您对此执行getAbsolutePath()时会发生什么。 Again from the javadoc: 再次从javadoc:

public String getAbsolutePath()

Returns the absolute pathname string of this abstract pathname. 返回此抽象路径名的绝对路径名字符串。 If this abstract pathname is already absolute, then the pathname string is simply returned as if by the getPath() method. 如果此抽象路径名已经是绝对路径,则仅通过getPath()方法返回路径名字符串。 If this abstract pathname is the empty abstract pathname then the pathname string of the current user directory, which is named by the system property user.dir , is returned. 如果此抽象路径名是空的抽象路径名,则返回由系统属性user.dir命名的当前用户目录的路径名字符串。 Otherwise this pathname is resolved in a system-dependent way. 否则,将以与系统有关的方式解析此路径名。 On UNIX systems, a relative pathname is made absolute by resolving it against the current user directory. 在UNIX系统上,通过根据当前用户目录解析相对路径名来使它成为绝对路径。

On Microsoft Windows systems, a relative pathname is made absolute by resolving it against the current directory of the drive named by the pathname, if any; 在Microsoft Windows系统上,通过将相对路径名与由该路径名命名的驱动器的当前目录(如果有)进行解析来使它成为绝对路径。 if not, it is resolved against the current user directory. 如果不是,则针对当前用户目录进行解析。

Do you see what is happening? 你看到发生了什么事吗? Especially, with respect to user.dir ? 特别是关于user.dir

More hints: 更多提示:

Now create another variable, eg 现在创建另一个变量,例如

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

Try the same operations on newFile . newFile上尝试相同的操作。 Try using getParent() on your previous one as well as on this one. 尝试在上一个和上一个上使用getParent() You'll see the difference. 您会看到差异。

I hope this helps clarify a few points for you :) 我希望这可以为您澄清几点:)

It is because File(String str) will call normalize, but getAbsolutePath will also call resolve, there is where the user.dir is being used. 这是因为File(String str)将调用normalize,但是getAbsolutePath也将调用resolve,这是在使用user.dir的地方。 Look at the following example. 看下面的例子。

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

Here is the output: 这是输出:

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

You can see the src code here: new File(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 您可以在此处看到src代码:new File(String str) http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/io/File.java#文件%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 getAbsolutePath: http : //grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/io/File.java#File.getAbsolutePath%28%29

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM