Java:File.exists()设置“时不一致”;user.dir";
JRE 6,在Windows XP上 使用不同的构造函数实例化两个文件对象会导致Java:File.exists()设置“时不一致”;user.dir";,java,filesystems,Java,Filesystems,JRE 6,在Windows XP上 使用不同的构造函数实例化两个文件对象会导致File.exists()方法中的结果不一致 免责声明:下面的代码是抽象代码,不是实际代码。我认为这根本不是文件分隔符问题。我首先要求得到早期反应,以防我错过了一个很好理解的问题。现在看来,重置user.dir系统属性是导致此问题的原因之一。下面的代码现在是可复制和可用的。您可以复制/粘贴Java类并进行尝试,它的行为应该与我列出的结果一致 设置: public class TestFileExists {
File.exists()
方法中的结果不一致
免责声明:下面的代码是抽象代码,不是实际代码。我认为这根本不是文件分隔符问题。我首先要求得到早期反应,以防我错过了一个很好理解的问题。现在看来,重置user.dir
系统属性是导致此问题的原因之一。下面的代码现在是可复制和可用的。您可以复制/粘贴Java类并进行尝试,它的行为应该与我列出的结果一致
设置:
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)));
}
}
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
创建文件夹体系结构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)));
}
}
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
结果:
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)));
}
}
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
我不明白行sub_a是否存在?false
,并且结果在机器之间不一致,也不与根初始路径ant一致。现在,结果与机器之间的一致
现在,如果您通过从命令行调用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
但是sub_a
的存在显然是误报,因为它检查的是另一个文件夹的存在,而不是getAbsolutePath()
所描述的文件夹
因此我强烈怀疑File.exists()
依赖于实际的Java执行路径,并且文件存在与绝对路径不一致,并且exists()
使用“user.dir”系统属性以外的另一个路径来检查文件系统
知道这个问题可能来自哪里吗?在这行:
File sub_b = new File(root.getAbsolutePath()+"/sub");
您应该使用常量File.separator(取决于基础系统),而不是硬编码的正斜杠。在这一行:
File sub_b = new File(root.getAbsolutePath()+"/sub");
您应该使用常量文件.separator
(取决于基础系统),而不是硬编码的正斜杠。我认为它是目录分隔符,因为Windows通常使用反斜杠“\”,而Linux使用普通斜杠“/”
尝试将行更改为:
File sub_b = new File(root.getAbsolutePath() + System.getProperty("file.separator") + "sub");
我认为这是目录分隔符,因为Windows通常使用反斜杠“\”而Linux使用普通斜杠“/”
尝试将行更改为:
File sub_b = new File(root.getAbsolutePath() + System.getProperty("file.separator") + "sub");
这可能是文件分隔符问题。在Windows上,标准的文件分隔符是反斜杠(\
)。当您创建sub_b
时,您将创建一个包含斜杠和反斜杠的路径名(作为字符串)。系统可能对此有点困惑。这可能是文件分隔符问题。在Windows上,标准的文件分隔符是反斜杠(\
)。当您创建sub_b
时,您将创建一个包含斜杠和反斜杠的路径名(作为字符串)。系统可能会对此有点困惑。这些结果应该是跨机器确定的。让我把它按行分解:
System.out.println("sub_a exists ? "+sub_a.exists());
在这里,您要问的是这个文件是否确实存在于文件系统中。假设该文件存在,则应始终返回相同的值
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)));
在这里,您正在与.equals()进行对象比较,它将调用FileSystem类对两个对象的路径对象进行比较(),而不是绝对路径
很可能是文件分隔符错误。尝试在sub_b的构造中替换File.separator,如下所示:
File sub_b = new File(root.getAbsolutePath()+File.separator+"sub");
这些结果应该是跨机器确定的。让我把它按行分解:
System.out.println("sub_a exists ? "+sub_a.exists());
在这里,您要问的是这个文件是否确实存在于文件系统中。假设该文件存在,则应始终返回相同的值
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)));
在这里,您正在与.equals()进行对象比较,它将调用FileSystem类对两个对象的路径对象进行比较(),而不是绝对路径
很可能是文件分隔符错误。尝试在sub_b的构造中替换File.separator,如下所示:
File sub_b = new File(root.getAbsolutePath()+File.separator+"sub");
文件
可以表示抽象路径。为tmp
创建文件
和从tmp
的绝对路径创建一个文件
将不会相等对象,尽管它们的绝对路径相等
我不确定sub_a是否不存在,但sub_b是否存在,但我怀疑这是否是一个分隔符问题。我怀疑这与以下声明有关:
每个路径名字符串都转换为抽象路径名,子抽象路径名根据父抽象路径名解析
我不知道在基于Unix的文件系统中,从/full/path/to
,/tmp/sub
将存在,但/full/path/to/tmp
将不存在
如果问题在系统之间是一致的,则可以通过转储更多每个文件
对象的状态来更清楚地理解问题,而不仅仅是打印比较。文件
可以表示抽象路径。为tmp
创建文件
和从tmp
的绝对路径创建一个文件
将不会相等对象,尽管它们的绝对路径相等
我不确定sub_a是否不存在,但sub_b是否存在,但我怀疑这是否是一个分隔符问题。我怀疑这与以下声明有关:
每个路径名字符串都是conv