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

发布于 12-19 02:47 字数 470 浏览 3 评论 0原文

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

已弃用。该方法存在不良的符号链接检测和竞争问题 状况。此功能只能由以下人员适当支持 shell 到操作系统命令,例如 rm -rf 或 del /s。 该方法计划在 Guava 版本中从 Guava 中删除 11.0

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

In Guava 10+, Google deprecated Files.deleteDirectoryContents(). JavaDoc says

Deprecated. This method suffers from poor symlink detection and race
conditions. This functionality can be supported suitably only by
shelling out to an operating system command such as rm -rf or del /s.
This method is scheduled to be removed from Guava in Guava release
11.0

I am confused on why there is a race condition. I think having this method is actually useful and find shelling out to operating system a poor solution. Can the authors share why the made this decision?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无远思近则忧2024-12-26 02:47:43

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

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

如果 directory 在检查期间是一个普通目录,但之后是一个到 / 的符号链接,deleteDirectoryContents 将很乐意尝试擦除整个目录文件系统。

也许有解决方法,但我们还没有找到。针对潜在的安全漏洞进行临时修复是很可怕的。

The race condition is potentially worse than "directory might not be empty," and this is in part because of the poor symlink detection. Consider this code snippet:

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

If directory is a plain directory during the check but a symlink to / afterward, deleteDirectoryContents will happily try to wipe the whole filesystem.

Maybe there's a workaround, but we haven't found it. And making ad hoc fixes for a potential security bug is scary.

泅人2024-12-26 02:47:43

有关损坏符号链接检测的更多示例,请参阅 用户提交的这些错误

简而言之,除非您提供该目录的规范路径,否则不可能擦除该目录。如果 /tmp 是指向 /some/other/directory 的链接,则 deleteDirectoryContents 无法擦除 /tmp/mytempdirectory >。也许这里也有一个可能的解决方法,但我们放弃了。

For more examples of broken symlink detection, see these bugs filed by users.

In short, it's impossible to wipe a directory unless you provide the canonical path to that directory. If /tmp is a link to /some/other/directory, deleteDirectoryContents can't wipe /tmp/mytempdirectory. Maybe there's a possible workaround here, too, but we threw up our hands.

满天都是小星星2024-12-26 02:47:43

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

例如,假设一个线程调用 Files.deleteDirectoryContents(),而第二个线程(或外部进程)同时在目录中创建一个新文件。
当您从通话中返回时,您可以相信该目录是空的吗?没有!

那么另一个进程在该目录上运行呢???它无法解决,您不应该处理交易,因为这是不可能的。有人认为有人将符号链接到根目录,所以我删除了整个文件系统 - 不应该访问文件系统的权限来处理这个问题吗?如果您以 root 身份运行此类操作,您应该知道自己在做什么。在文件系统中完全禁用删除文件怎么样,这是危险的!如果 Guava 的作者解决了这些愚蠢的问题,我将使用不同的库。

Are you serious? You are trying to solve multithreading operations:

For example, suppose that one thread calls Files.deleteDirectoryContents() and a second thread (or an external process) simultaneously creates a new file in the directory.
When you return from the call, can you rely on the directory being empty? Nope!

And what about another process operates on the directory??? It cannot be solved and you should not handle transactions since it is simply not possible. And argument that somebody makes symlink to root so I delete whole filesystem - should not acccess rights to filesystem handle that? And if you are running such operation as root you should know what you are doing. What about disable deleting files at all in filesystem, it is dangerous!!! I will use different library then if authors of Guava solve such idiotic problems.

貪欢2024-12-26 02:47:42

我对为什么存在竞争条件感到困惑。

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

当您从通话中返回时,您可以相信该目录是空的吗?没有!

无论如何,如果您发现此方法的功能很有用......尽管它有缺陷......您可以自由地获取代码的副本,对其进行调整并将其嵌入到您的应用程序中。 (只需检查 Guava 源代码许可证并确保您遵守它。)

作者能否分享为什么做出这个决定?

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

I am confused on why there is a race condition.

For example, suppose that one thread calls Files.deleteDirectoryContents() and a second thread (or an external process) simultaneously creates a new file in the directory.

When you return from the call, can you rely on the directory being empty? Nope!

Anyway, if you find the functionality of this method to be useful ... despite its flaws ... you are free to take a copy of the code, tweak it, and embed it in your application. (Just check the Guava source code license and make sure that you conform to it.)

Can the authors share why the made this decision?

I think that they already have; see the deprecation notice. If you want more, try searching the issue tracker and the Guava discussion group. You could even try asking politely on the discussion group, though if your agenda is to change their minds, I doubt that you will succeed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文