如何判断文件是否为指定目录的后代?

10 投票
3 回答
1422 浏览
提问于 2025-04-16 01:48

从表面上看,这个问题挺简单的,我自己也能轻松实现。只需要一个一个地调用dirname(),逐层向上检查文件路径中的每个目录,看看是不是我们要查找的那个目录。

但是,符号链接(symlink)让事情变得复杂。路径中的任何一个目录,或者正在检查的文件的目录,都可能是一个符号链接,而任何符号链接又可以指向其他符号链接,形成任意的链接链。到这个时候,我的脑袋就有点懵了,不知道该怎么办。我尝试写代码来处理这些特殊情况,但很快就变得太复杂了,我觉得自己可能做错了。有没有什么比较优雅的方法来解决这个问题呢?

我在用Python,所以如果有哪个库可以处理这个问题,那就太好了。否则,这个问题在不同的编程语言中都是比较通用的。

3 个回答

4

在Python 3中,还有另一种方法可以做到这一点,就是使用pathlib这个库:

from pathlib import Path

is_descendant = Path("/the/dir") in Path(filename).resolve().parents

你可以查看Path.resolve()Path.parents的文档了解更多信息。

4

Python 3.5 有一个很实用的功能,叫做 os.path.commonpath

这个功能会返回一组路径中,最长的公共子路径。如果路径中同时包含绝对路径和相对路径,或者路径列表是空的,它会报错。跟 commonprefix() 不同的是,这个功能返回的是一个有效的路径。

所以,如果你想检查一个文件是否在某个目录下,你可以这样做:

os.path.commonpath(["/the/dir", os.path.realpath(filename)]) == "/the/dir"

commonprefix 不同的是,你不需要担心输入的路径后面有没有斜杠。使用 commonprefix 时,返回的结果总是没有斜杠的。

10

使用 os.path.realpathos.path.commonprefix

os.path.commonprefix(['/the/dir/', os.path.realpath(filename)]) == "/the/dir/"

os.path.realpath 可以把任何符号链接和文件名中的 .. 展开成真实的路径。而 os.path.commonprefix 有点不靠谱——它其实并不是在检查路径,而只是比较字符串的前缀,所以你需要确保你的目录后面有一个目录分隔符。如果没有,它会错误地认为 /the/dirtwo/filename 也在 /the/dir 里面。

撰写回答