为什么“File.exists”返回 true,即使 NIO “Files” 类中的 “Files.exists” 返回 false

2022-09-02 22:25:09

我正在尝试确定网络文件夹中是否存在文件:

// File name is "\\QWERTY\folder\dir\A123456.TXT"
Path path = Paths.get("\\\\QWERTY\\folder\\dir\\A123456.TXT")

使用蔚来汽车 :Files

Files.exists(path) == false

用:File

path.toFile().exists() == true

根据我们的测试,使用似乎是正确的。为什么比 ?FileFileFiles

那么,它是什么呢?不能两者兼而有之!

但是等等,还有.Files.notExists(path)

当网络共享文件实际存在时

Files.exists(path): false
Files.notExists(path): false
path.toFile().exists(): true

当网络共享文件实际上不存在

Files.exists(path): false
Files.notExists(path): true
path.toFile().exists(): false

另一种同样疯狂的方式来看待上述三个结果

boolean exists = Files.exists(path) || !Files.notExists(path)
boolean notExists = Files.notExists(path) || !Files.exists(path)
boolean oldFashionedExists = path.toFile().exists()

:笑脸:

环境和注释

该程序在 Windows 8.1 专业版 32 位计算机(操作系统和计算机)上运行,并从 Windows 2008 R2(32 位)计算机检查网络共享。

为了确定 Files.exists 失败,我安装了一个 WatchService 来监视该文件夹,并在检查 Files.exists 时看到该文件确实存在。然后,我记录了这两种方法,并发现File.exists是正确的方法。

现在,在我的代码中,我检查为.Files.exists(path) || path.toFile().exists()

有点愚蠢,必须同时做这两件事。也许可以逃脱后来的惩罚。只是试图让甲骨文的工程师们从怀疑中获益,但整个事情是相当愚蠢的,因为他们报告的不同。

另外,我不在乎“存在”是否立即过时。我只想知道该文件在我们检查的那一刻是否存在。我从来没有遇到过这种情况 - 我们花了30个小时在我和另一个开发人员之间试图弄清楚为什么我们的程序由于这个“功能”而没有接口。

冥想一会儿

File.exists():当且仅当此抽象路径名所表示的文件或目录存在时,返回 true;否则为假。

Files.exists(): 如果文件存在,则返回 true;如果文件不存在或无法确定其存在,则为 false。

这让我崩溃了!“当且仅当此抽象路径名所表示的文件或目录存在时;false 否则“与”如果文件存在,则为 true;如果文件存在;如果文件存在,则为 false如果文件不存在或无法确定其存在,则为 false”

那么,如果“无法确定存在”,怎么可能仍然是正确的呢?显然,存在可以(并且正在)由File决定,但不能由File决定。File.exists


答案 1

至于为什么两者之间可能有区别,请对比他们的文档:

File.exists():当且仅当此抽象路径名所表示的文件或目录存在时,返回 true;否则为假。

Files.exists(): 如果文件存在,则返回 true;如果文件不存在或无法确定其存在,则为 false。

这可能解释了两者之间的差异,也许一个在确定文件的存在方面遇到了麻烦。Files

例如,在 Linux 下,可以设置目录和文件权限,以便您可以打开已存在但看不到它存在的文件(通过取消对文件所在目录的读取权限,同时保持文件权限更开放)。

根据 Oracle 的更多文档,仅当文件被验证存在时才返回。Files.exists()true

返回值 并不意味着它不存在。false

他们建议你同时使用这两种方法,并涵盖三种可能性,例如:exists()notExists()

if (Files.exists(fspec)) {
    System.out.println("It exists!");
else if (Files.notExists(fspec)) {
    System.out.println("It does not exist!");
else
    System.out.println("I have no idea!");

这涵盖了上面该链接中涵盖的文件状态的三种可能性:

  • 验证该文件是否存在。
  • 验证该文件不存在。
  • 文件的状态未知。当程序无权访问该文件时,可能会发生此结果。

答案 2

我有同样的问题,但你的黑客对我没有帮助。当文件实际存在时,所有方法都返回我为假:

Files.exists(path) = false, 
path.toFile().exists() = false, 
Files.notExists(path) = true, 
Files.exists(path) || path.toFile().exists() = false

但是,如果此时在资源管理器中打开了包含此文件的网络目录,则正确处理了它的存在。

我通过在目录中创建一个新文件(然后删除它)来解决这个问题:

Files.createFile(Paths.get(path.getParent().toString(), "test"));

在该命令之后,显然,Windows会更新有关文件夹的信息