如何判断为啥在 Java 中文件删除失败?
Posted
技术标签:
【中文标题】如何判断为啥在 Java 中文件删除失败?【英文标题】: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)
的良好实现了吗?否则我只好自己写了。
【问题讨论】:
【参考方案1】:不幸的是,在 Java 6 中,无法确定文件无法删除的原因。在 Java 7 中,您可以改用java.nio.file.Files#delete()
,如果无法删除文件或目录,它将为您提供详细的失败原因。
请注意,file.list() 可能会返回目录条目,这些条目可以被删除。删除的 API 文档说只能删除空目录,但如果包含的文件是例如目录,则目录被认为是空的。操作系统特定的元数据文件。
【讨论】:
Java 7 API 中似乎不存在这种删除方法。 link 编辑:刚刚发现它现在在 Files 类中。 link 文件删除失败会抛出异常吗?返回类型是无效的!它的文档不清楚。在这里提问:***.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】:删除可能由于一个或多个原因而失败:
-
文件不存在(使用
File#exists()
进行测试)。
文件被锁定(因为它是由另一个应用程序(或您自己的代码!)打开的!)。
您未获得授权(但这会引发 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。
【讨论】:
以上是关于如何判断为啥在 Java 中文件删除失败?的主要内容,如果未能解决你的问题,请参考以下文章