2011-11-30 79 views
9

在Guava 10+中,Google已弃用Files.deleteDirectoryContents()。 JavaDoc说为什么在Guava中不推荐使用Files.deleteDirectoryContents()?

已弃用。这种方法遇到糟糕的符号链接检测和竞争条件。此功能仅适用于支持操作系统命令(例如rm -rf或del/s)的 。 此方法定于番石榴番石榴除去释放 11.0

我对为什么会出现竞争条件困惑。我认为这种方法实际上很有用,并且发现向操作系统提出一个糟糕的解决方案。作者可以分享为什么做出这个决定吗?

+0

更清晰,我觉得有竞争状态的问题不是主要的错误。许多库,像'ArrayList'不是线程安全的或者有竞争条件。即使'File.remove'也有同样的问题。但他们都记录在案。所以我希望听到一个答案,除了文件已经说了他们为什么选择使其不推荐使用。 –

+1

这种竞争条件和典型的非线程安全类之间的区别在于它没有“修复”。相比之下,您可以通过同步锁对象来解决非线程安全类的Java线程安全问题。一种根本无法做到人们所期望的方法是一种不好的方法。 –

+0

这是一个很好的观点。谢谢。 –

回答

5

我很困惑为什么有一个竞争条件。

例如,假设一个线程调用Files.deleteDirectoryContents()和第二螺纹(或外部过程)同​​时在目录中创建新的文件。

当您从通话中返回时,您可以依赖目录为空吗?不!

无论如何,如果你发现这个方法的功能是有用的......尽管它的缺陷......你可以自由地获取代码的副本,调整它,并将其嵌入到你的应用程序中。 (只需检查番石榴的源代码许可证,并确保符合它。)

作者可以分享为什么做出此决定?

我认为他们已经有;请参阅弃用通知。如果您需要更多,请尝试搜索问题跟踪器和Guava讨论组。你甚至可以尝试在讨论小组中礼貌地问,但如果你的议程要改变他们的想法,我怀疑你会成功。

+4

炮击到操作系统也是如此,不是吗? – anders

+0

+1对OS不一样。我认为如果一个库不是线程安全的,那么它应该被记录下来,并由开发人员确定它们是否正确使用它。 –

+0

@Stephen C,我不想改变任何身体的想法。我肯定有一个很好的理由,为什么这是不赞成的。我只是觉得除了竞赛状况之外,还有一个问题可能会被迫做。但有很多库存有竞争条件。我想也许会有更好的理由。 –

5

竞争条件可能比“目录可能不为空”更糟糕,这部分是由于糟糕的符号链接检测。考虑下面的代码片段:

// Symbolic links will have different canonical and absolute paths 
if (!directory.getCanonicalPath().equals(directory.getAbsolutePath())) { 
    return; 
} 
... delete its contents ... 

如果directory是在检查过程中一个普通的目录,但一个符号链接/之后,deleteDirectoryContents将愉快地试图消灭整个文件系统。

也许有一个解决方法,但我们还没有找到它。为潜在的安全漏洞做临时修复是可怕的。

1

有关断链符号链接检测的更多示例,请参阅these bugs filed by users

总之,除非您提供该目录的规范路径,否则不可能擦除目录。如果/tmp/some/other/directory的链接,则deleteDirectoryContents无法清除/tmp/mytempdirectory。也许这里也有可能的解决方法,但我们举起手来。

1

你是认真的吗?您正试图解决多线程操作:

例如,假设一个线程调用文件。deleteDirectoryContents()和第二个线程(或外部进程)同时在目录中创建一个新文件。 当您从通话中返回时,您可以依赖目录为空吗?不!

又是怎么回事另一个进程上的目录操作???它不能解决,你不应该处理交易,因为这是不可能的。并且有人认为有人将symlink连接到root,所以我删除整个文件系统 - 不应该获得文件系统处理该权限的权限?如果你正在运行root这样的操作,你应该知道你在做什么。怎么样在文件系统中禁用删除文件,这是危险的!如果番石榴的作者解决这些白痴问题,我将使用不同的图书馆。

相关问题