【问题标题】:Alternative to File.exists() in JavaJava 中 File.exists() 的替代方案
【发布时间】:2020-12-08 23:28:10
【问题描述】:

我从没想过它会发生在我身上,但我遇到了我在 Java 中的第一个错误:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5003595

我几乎处于与错误(Linux 上的 NFS)中描述的完全相同的情况,我看到 File.exists() 没有返回正确的值(至少不是马上)。

所以我的问题是,除了这种检查文件是否存在的方法之外,还有其他方法吗?如果可能的话,我更愿意让它与操作系统无关。

编辑:我找到了解决方法。如果您调用ls $filedir,NFS 会刷新任何给Java 带来麻烦的缓存/元数据,并且File.exists() 返回正确的值。当然,这并不完全理想,因为它会损害便携性,但有一些方法可以解决这个问题。

【问题讨论】:

  • 是什么样的文件?您在寻找特定类型的文件吗?或者只是任何文件?您可以运行 System.exec("ls") 并解析文件的结果。虽然我确信有更简单的方法,所以我会将此作为评论
  • 这个错误是 Java 1.4.2_03 特有的,它在几年前就已经结束了支持生命周期。出于好奇,为什么不直接迁移到 Java 5 或更高版本?您是否尝试过使用受支持的 JRE 进行测试以查看是否有任何中断?
  • @Steve:我正在运行 Java 6。我假设由于他们为这个错误标记了“不会修复”,所以它在任何版本的 Java 中都没有修复。至少,这就是我的应用程序的行为告诉我的。
  • 奇怪。我同意下面的 Ben,因为 File.exists() 可以报告误报(即说文件不存在时存在)。然而,假否定是不同的(即当文件就在那里时说文件不存在)。该错误报告已有 6 年多的历史了,并且 cmets 表示他们在 JSR 203 的开发中解决了这个问题......所以如果你仍然在当代 JRE 中看到这个,我会提交一个新的错误报告。但是,下面的两个答案几乎是正确的......最好的解决方法是简单的 try-catch 块。

标签: java file-io java-io nfs java-nio


【解决方案1】:

NFS 的基本问题是它缓存属性、文件和目录信息。这意味着信息可能已过时。您或许可以关闭缓存,您会发现性能显着下降。

要记住的重要一点是,NFS 不是一种消息传递服务,也不是为及时传递数据而设计的。

【讨论】:

  • 这差不多是我可以标记的答案。问题实际上更接近于使用 NFS 的事实。在我的情况下,创建了一个文件名为 x.file 的文件,然后将其删除,然后使用相同的名称 (x.file) 重新创建。重新制作后,对文件的 stat 调用声称它不存在。在整个目录上调用 'ls' 似乎会刷新缓存并修复 Java 的 file.exists() 问题,并且对 stat 的调用也开始正确返回。这似乎表明问题更多与 NFS 相关,而不是 Java。
【解决方案2】:

我遇到了同样的问题,并通过致电file.getParentFile().list() 解决了它。与您的解决方案基本相同,但与操作系统无关。

【讨论】:

  • @SteveCohen 它可能会破坏正在查看的任何缓存。在这种情况下,它也意味着性能损失。
【解决方案3】:

如果File.exists() 返回 true,然后有人删除文件/您的 NFS 挂载消失,然后您尝试打开文件,会发生什么?基本上,File.exists() 是无用的,因为您需要处理打开文件时可能出现的异常。

【讨论】:

    【解决方案4】:

    所有File.exists 告诉您该文件是否在过去的某个时间点存在。它没有告诉你:

    • 尝试打开时是否存在
    • 您是否有权限打开它
    • 任何有用的东西,真的

    因此,请尝试设计您的应用程序,使其能够处理不存在的文件,而无需事先进行检查。 (在实际使用文件时,您必须处理各种异常。)

    【讨论】:

    • 您假设我稍后会打开该文件,但在我的特定情况下并非如此。我实际上根本没有在我的应用程序中打开文件。我正在检查是否存在其他原因。
    【解决方案5】:

    我注意到如果文件不存在或无法确定它的存在,Java 7 的 java.nio.file.Path.exists() 方法会返回 false。因此,假阴性似乎会存在一段时间,您的代码需要容忍它们。

    【讨论】:

      【解决方案6】:

      显而易见的替代方案是File.isFile()。先试试看。

      虽然读取只读文件时会变得不准确,但您始终可以使用File.canWrite() 来检查文件是否存在。

      如果以上两种方法都失败,您可以使用File.length()。如果它返回0L,则表明该文件不存在。

      【讨论】:

        猜你喜欢
        • 2012-07-26
        • 2013-03-10
        • 2013-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-28
        • 2015-04-29
        • 1970-01-01
        相关资源
        最近更新 更多