Java中删除非空目录

35
假设我有一个代表目录的File f,那么f.delete()仅在目录为空时才会删除该目录。我在网上找到了几个使用File.listFiles()File.list()获取目录中所有文件并递归遍历目录结构并删除所有文件的例子。但是,由于可以创建无限递归的目录结构(在Windows和Linux(具有符号链接)中),因此可能程序以这种方式编写可能永远不会终止。
那么,有没有更好的方法来编写这样的程序,以使其不陷入这些陷阱?我需要跟踪我已经遍历过的所有地方并确保我不会绕圈子走还是有更好的方法? 更新:回应一些答案(谢谢!)-我希望代码不要遵循符号链接并保留在它应该删除的目录中。即使在Windows情况下,我能依靠Commons-IO实现来做到这一点吗?
5个回答

42
如果你真的希望递归目录删除遵循符号链接,那么我认为没有任何跨平台的方法可以在不跟踪所有已遍历目录的情况下实现。但是,在我能想到的几乎每种情况下,你只需要删除指向目录的实际符号链接,而不是递归地遍历符号链接。如果这是你想要的行为,那么你可以使用Apache Commons IO中的FileUtils.deleteDirectory方法。

9
尝试使用经过测试的实现——Apache Commons IO

但是,我认为它不能解决无限递归的问题。


2
查看源代码:http://svn.apache.org/viewvc/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java?view=markup 您会发现deleteDirectory函数不会遵循符号链接。 - elou

3

File.getCanonicalPath()方法可以告诉您文件的“真实”名称,包括已解析的符号链接。当扫描过程中遇到已知目录(因为您将它们存储在Map中)时,请退出。


我认为这会使递归删除变慢。你不能使用File.getPath().equals(File.getCanonicalPath())吗? - Henry B
我不确定你想要处理多少个递归目录,但是每个目录使用Map.put()和Map.contains()不会减慢速度。你提出的代码只会告诉你在你的路径中某处有符号链接。它们可能在你想要删除的目录上面。 - Bombe
2
说实话,先担心完成工作。只有当它完美运行并且您可以测量它的速度太慢(无论这意味着什么),只有在那时开始担心性能。过早优化是如此愚蠢,以至于让我感到痛苦。身体上的痛苦。 - Bombe

0
如果您能知道哪些文件是符号链接,您就可以跳过它们。
不幸的是,在Java中没有“干净”的方法来检测符号链接。请查看this纯Java解决方案或涉及本地代码的this one

0

至少在MacOSX下,删除指向目录的符号链接不会删除目录本身,因此即使目标目录不为空也可以被删除。

我认为这适用于大多数POSIX操作系统。据我所知,Windows下的链接也只是文件,可以从Java程序中像删除文件一样删除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接