Java:设置"user.dir"时File.exists()不一致

glm*_*ndr 9 java filesystems

JRE 6,在Windows XP上.

使用不同构造函数实例化两个File对象会导致该File.exists()方法的结果不一致.

免责声明:以下代码是摘要,而不是实际代码.我根本不相信这是一个File.separator问题.我首先要求得到早期反应,以防我错过了一个很好理解的问题.现在看来,重置系统属性是导致此问题的原因之一.下面的代码现在可以重现并且可以按原样使用.您可以复制/粘贴Java类并尝试它,它应该与我列出的结果一致. user.dir

建立:

创建文件夹架构C:\toto\tmp\sub.

从任何不包含tmp/sub子文件夹体系结构的文件夹中启动以下类.

码:

public class TestFileExists {

    public static void main(String[] args) {

        System.setProperty("user.dir", "C:\\toto\\");

        File root = new File("tmp");

        File sub_a = new File(root, "sub");

        File sub_b = new File(root.getAbsolutePath()+"/sub");

        System.out.println("sub_a path ? "+sub_a.getAbsolutePath());
        System.out.println("sub_a exists ? "+sub_a.exists());
        System.out.println("sub_b path ? "+sub_b.getAbsolutePath());
        System.out.println("sub_b exists ? "+sub_b.exists());
        System.out.println("Path equals ? "+ (sub_a.getAbsolutePath().equals(sub_b.getAbsolutePath())));
        System.out.println("Obj equals ? "+ (sub_a.equals(sub_b)));

    }

}
Run Code Online (Sandbox Code Playgroud)

结果:

sub_a path ? C:\toto\tmp\sub
sub_a exists ? false
sub_b path ? C:\toto\tmp\sub
sub_b exists ? true
Path equals ? true
Obj equals ? false
Run Code Online (Sandbox Code Playgroud)

我不理解这条线sub_a exists ? false,结果在机器与机器之间不一致,也没有与根初始路径一致,结果现在与机器一致.

现在,如果您通过从命令行调用java来重新执行该类,从包含tmp/sub子文件夹体系结构的文件夹(如果您调用它D:\,具有D:\tmp\sub),您将得到预期的:

sub_a path ? C:\toto\tmp\sub
sub_a exists ? true
sub_b path ? C:\toto\tmp\sub
sub_b exists ? true
Path equals ? true
Obj equals ? false
Run Code Online (Sandbox Code Playgroud)

但这种存在sub_a显然是一种误报,因为它检查了另一个文件夹的存在而不是所描述的文件夹getAbsolutePath().

所以我强烈怀疑这File.exists()取决于实际的Java执行路径,并且该文件存在与绝对路径不一致,并exists()使用另一个路径而不是"user.dir"系统属性来检查文件系统.

知道这个问题可能来自哪里?

Joa*_*uer 10

设置user.dir不受支持.它应该被视为只读属性.

例如,Sun Bug Parade中对Bug 4117557的评估包含以下文本:

在jvm启动期间初始化的"user.dir"应该用作信息性/只读系统属性,尝试通过命令行自定义它-Duser.dir = xyz将最终实现dependend/unspecified行为.

虽然本文是关于在命令行上设置它,但设置它setProperty()很可能同样未定义.

如果您可以在user.dir手动设置的情况下重现问题,那么您就找到了一个真正的问题.