为什么在Guava中不推荐使用Files.deleteDirectoryContents()?

时间:2011-11-30 02:19:02

标签: java guava deprecated

在Guava 10+中,Google弃用Files.deleteDirectoryContents()。 JavaDoc说

  

已过时。这种方法的符号链接检测和竞争都很差   条件。只能通过以下方式适当支持此功能   shelling out到操作系统命令,例如rm -rf或del / s。   计划在Guava版本中从Guava中删除此方法   11.0

我很困惑为什么会有竞争条件。我认为使用这种方法实际上是有用的,并找到一个糟糕的解决方案。作者可以分享为什么做出这个决定?

4 个答案:

答案 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的作者解决了这些愚蠢的问题,我会使用不同的库。