Why is Files.deleteDirectoryContents() deprecated

2019-06-16 07:20发布

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?

4条回答
冷血范
2楼-- · 2019-06-16 07:33

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.

查看更多
疯言疯语
3楼-- · 2019-06-16 07:37

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.

查看更多
姐就是有狂的资本
4楼-- · 2019-06-16 07:40

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.

查看更多
啃猪蹄的小仙女
5楼-- · 2019-06-16 07:47

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.

查看更多
登录 后发表回答