如何判断目录是否是python中的Windows联结

时间:2017-11-24 09:12:13

标签: python windows filesystems symlink

我正在os.walk()上运行"C:\Users\confusedDev\Documents",我看到["My Music", "My Pictures"...]作为subDirs返回,但实际上并未访问它们。经过一些研究后,我发现它们在Windows中实际上是junctions

我的理解是,结点是指向目录的符号链接,默认情况下会在os.walk()期间被忽略,但是以下测试失败了我

>>> os.path.islink("C:\\Users\\confusedDev\\Documents\\My Pictures")
False

嗯...... os.walk()怎么知道" C:\ Users \ confusedDev \ Documents \ My Pictures"是" C:\ Users \ confusedDev \ Pictures"的符号链接。并且需要被跳过?我想调用相同的API ...现在,我的解决方法逻辑假定如果os.walk()跳过一个目录,它就是一个结点

3 个答案:

答案 0 :(得分:1)

使用python3.5islinkjunction links返回false。似乎python3.5本身不支持联结链接,但可以使用ctypes或外部库添加对联结链接的支持:

  1. 将外部模块用于ntfs:https://github.com/Juntalis/ntfslink-python/tree/master/ntfslink

  2. 在pywin32中使用win32模块:http://docs.activestate.com/activepython/2.5/pywin32/win32file__CreateSymbolicLink_meth.html

  3. 直接致电dll:https://stackoverflow.com/a/1143276/4752883

  4. 这些是更复杂的解决方案。此外,如果您使用junction links,它们将无法在以前版本的Windows或其他操作系统上运行。

    TL; DR 为了使其可移植,最好使用junction links代替symbolic linksmklink /D转换为mklink /Jsymbolic linksos.walk可识别os.path.islink

答案 1 :(得分:1)

我要使用的另一种方法是子进程。只需调用提供有关Windows中链接信息的外部Windows程序,如果链接存在则返回0作为返回码,如果链接不存在或不是链接则返回0:

fsutil reparsepoint query "<PathToTest>"

例如这样的东西:

src = "C:\\Windows"
child = subprocess.Popen(
    "fsutil reparsepoint query \"{}\"".format(src),
    stdout=subprocess.PIPE
)
streamdata = child.communicate()[0]
rc = child.returncode

if rc == 0:
    print("Link exists")

在Windows 10上,可以像普通用户一样正常工作(也可以创建链接),但是对于Windows 7,则需要管理员权限。对我来说不是问题,因为我的应用程序将检查链接以创建一个新链接,因此无论如何它都需要Windows 7上的管理员权限。

问候!

答案 2 :(得分:1)

有点晚了,但是您可以尝试将os.readlink()包裹起来,除了目录连接之外,然后将其放在可以调用的函数中,如下所示:

def is_junction(path: str) -> bool:
    try:
        return bool(os.readlink(path))
    except OSError:
        return False