【问题标题】:How to tell why a file deletion fails in Java?如何判断为什么在 Java 中文件删除失败?
【发布时间】:2010-12-16 06:55:58
【问题描述】:
File file = new File(path);
if (!file.delete())
{
    throw new IOException(
        "Failed to delete the file because: " +
        getReasonForFileDeletionFailureInPlainEnglish(file));
}

已经有getReasonForFileDeletionFailureInPlainEnglish(file) 的良好实现了吗?否则我只好自己写了。

【问题讨论】:

    标签: java file-io error-handling jdk1.6 jdk6


    【解决方案1】:

    不幸的是,在 Java 6 中,无法确定文件无法删除的原因。在 Java 7 中,您可以改用java.nio.file.Files#delete(),如果无法删除文件或目录,它将为您提供详细的失败原因。

    请注意,file.list() 可能会返回目录条目,这些条目可以被删除。删除的 API 文档说只能删除空目录,但如果包含的文件是例如目录,则目录被认为是空的。操作系统特定的元数据文件。

    【讨论】:

    • Java 7 API 中似乎不存在这种删除方法。 link 编辑:刚刚发现它现在在 Files 类中。 link
    • 文件删除失败会抛出异常吗?返回类型是无效的!它的文档不清楚。在这里提问:stackoverflow.com/questions/19935624/…
    【解决方案2】:

    Java 7 java.nio.file.Files类也可以使用:

    http://docs.oracle.com/javase/tutorial/essential/io/delete.html

    try {
        Files.delete(path);
    } catch (NoSuchFileException x) {
        System.err.format("%s: no such" + " file or directory%n", path);
    } catch (DirectoryNotEmptyException x) {
        System.err.format("%s not empty%n", path);
    } catch (IOException x) {
        // File permission problems are caught here.
        System.err.println(x);
    }
    

    【讨论】:

      【解决方案3】:

      请注意,阻止文件被删除的可能是您自己的应用程序!

      如果您之前写入文件并且没有关闭写入器,则您自己锁定了文件。

      【讨论】:

      • 在使用 Java 6 在 Windows 7 上进行测试时,我的阅读器也遇到了这个问题。我尝试在关闭阅读器之前删除文件,但失败了。
      【解决方案4】:

      嗯,我能做到的最好:

      public String getReasonForFileDeletionFailureInPlainEnglish(File file) {
          try {
              if (!file.exists())
                  return "It doesn't exist in the first place.";
              else if (file.isDirectory() && file.list().length > 0)
                  return "It's a directory and it's not empty.";
              else
                  return "Somebody else has it open, we don't have write permissions, or somebody stole my disk.";
          } catch (SecurityException e) {
              return "We're sandboxed and don't have filesystem access.";
          }
      }
      

      【讨论】:

      • @Cory、file.exists()、isDirectory() 和 list() 都可以抛出 SecurityExcepions。
      • @Bob:这只发生在沙盒中。原来的 delete() 很可能也抛出了 SecurityException。但为了完整起见,我想他应该抓住它(并返回“沙盒:无文件系统访问”)
      • @Thilo 补充说,但是,是的,我正在解决所提出的问题,而不是在从事文件 I/O 时的所有其他可能性。 :)
      【解决方案5】:

      删除可能由于一个或多个原因而失败:

      1. 文件不存在(使用File#exists() 进行测试)。
      2. 文件被锁定(因为它是由另一个应用程序(或您自己的代码!)打开的!)。
      3. 您未获得授权(但这会引发 SecurityException,而不是返回 false!)。

      因此,每当删除失败时,请执行File#exists() 以检查它是由 1) 还是 2) 引起的。

      总结:

      if (!file.delete()) {
          String message = file.exists() ? "is in use by another app" : "does not exist";
          throw new IOException("Cannot delete file, because file " + message + ".");
      }
      

      【讨论】:

      • @BalusC,记住 file.exists() 也可以抛出 SecurityException。
      • 如果由于文件系统权限而导致删除失败,您将不会收到 SecurityException。
      • 只有当你的 JVM 被限制性地配置时,你才会得到 SecurityException,例如,如果你是一个小程序。 “正常”的应用程序不会在这里被沙盒化。
      • @Bob:然后将其全部包装在 SecurityException 上的 try/catch 块中。 @Thilo:我没有说任何关于文件系统权限的事情。几乎是任何级别的授权失败。
      【解决方案6】:

      正如File.delete()中指出的那样

      您可以使用为您抛出异常的 SecurityManager。

      【讨论】:

        猜你喜欢
        • 2011-01-01
        • 1970-01-01
        • 2017-04-04
        • 1970-01-01
        • 1970-01-01
        • 2015-11-15
        • 2020-11-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多