在Guava 10+中,Google弃用Files.deleteDirectoryContents()。 JavaDoc说
已过时。这种方法的符号链接检测和竞争都很差 条件。只能通过以下方式适当支持此功能 shelling out到操作系统命令,例如rm -rf或del / s。 计划在Guava版本中从Guava中删除此方法 11.0
我很困惑为什么会有竞争条件。我认为使用这种方法实际上是有用的,并找到一个糟糕的解决方案。作者可以分享为什么做出这个决定?
答案 0 :(得分:5)
我对为什么会有竞争条件感到困惑。
例如,假设一个线程调用Files.deleteDirectoryContents()
,第二个线程(或外部进程)同时在目录中创建一个新文件。
当您从通话中返回时,您是否可以依赖目录为空?都能跟得上!
无论如何,如果您发现此方法的功能有用......尽管有其缺陷......您可以自由地复制代码,进行调整并将其嵌入到您的应用程序中。 (只需检查Guava源代码许可证并确保符合它。)
作者能否分享为何做出这个决定?
我认为他们已经拥有;请参阅弃用通知。如果您想要更多,请尝试搜索问题跟踪器和Guava讨论组。您甚至可以尝试礼貌地询问讨论组,但如果您的议程改变主意,我怀疑您会成功。
答案 1 :(得分:5)
竞争条件可能比“目录可能不为空”更糟糕,这部分是因为符号链接检测不佳。请考虑以下代码段:
// Symbolic links will have different canonical and absolute paths
if (!directory.getCanonicalPath().equals(directory.getAbsolutePath())) {
return;
}
... delete its contents ...
如果directory
在检查期间是一个普通目录,但后来是/
的符号链接,deleteDirectoryContents
将很乐意尝试擦除整个文件系统。
也许有一种解决方法,但我们还没有找到它。对潜在的安全漏洞进行临时修复是可怕的。
答案 2 :(得分:1)
有关符号链接检测损坏的更多示例,请参阅these bugs filed by users。
简而言之,除非您提供该目录的规范路径,否则无法擦除目录。如果/tmp
是/some/other/directory
的链接,则deleteDirectoryContents
无法删除/tmp/mytempdirectory
。也许这里有一个可能的解决方法,但我们举手了。
答案 3 :(得分:1)
例如,假设一个线程调用Files.deleteDirectoryContents(),第二个线程(或外部进程)同时在目录中创建一个新文件。 当您从通话中返回时,您是否可以依赖该目录为空?都能跟得上!
然后另一个进程在目录上运行???它无法解决,您不应该处理交易,因为它根本不可能。并且有人将符号链接设为root所以我删除整个文件系统的论点 - 不应该获得文件系统处理权限吗?如果你以root身份运行这样的操作,你应该知道你在做什么。怎么样在文件系统中禁用删除文件,这很危险!如果Guava的作者解决了这些愚蠢的问题,我会使用不同的库。