【问题标题】:File/FileInputStream relative path strange behaviourFile/FileInputStream 相对路径奇怪的行为
【发布时间】:2013-09-19 22:24:38
【问题描述】:

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

下面是sn-ps的代码及其返回值(=之后):

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() 返回的文件路径不正确。

【问题讨论】:

  • 您能否提供完成所有日志记录和测试的代码,以便我们自己更轻松地进行测试?
  • 示例代码已添加。
  • 这两种情况都可以打印 file.getPath() 吗?似乎有一个内部为字符串调用的解析方法,getPath 将打印而不解析任何内容。
  • q.txt/home/alex/projects/poltava/rpgu/workingdir/q.txt 分别

标签: java file


【解决方案1】:

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

一点帮助您入门的解释:

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

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

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

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

当您对此执行 getAbsolutePath() 时会发生什么。再次来自 javadoc:

public String getAbsolutePath()

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

在 Microsoft Windows 系统上,相对路径名是绝对的 通过根据驱动器的当前目录解析它 路径名,如果有的话;如果不是,则针对当前解决 用户目录。

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

更多提示:

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

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

newFile 上尝试相同的操作。尝试在上一个和这个上使用getParent()。你会看到区别的。

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

【讨论】:

  • 谢谢。它为我澄清了一些事情。那么,我们可以说在我的示例中使用相对路径是不正确的吗?
  • @sasha_trn:你是对的。对应于您要实现的用例,您对相对路径的使用不正确。
【解决方案2】:

这是因为 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 代码: 新文件(字符串 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

获取绝对路径: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/io/File.java#File.getAbsolutePath%28%29

【讨论】:

  • 在 Linux 机器上,我有以下示例输出:/home/alex/projects/poltava/rpgu/workingdir Test.txt /home/alex/projects/poltava/rpgu/workingdir/Test.txt
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多