在Windows上使用Python的os.path.islink

12 投票
5 回答
6704 浏览
提问于 2025-04-17 18:11

在Windows 7上用Python 2.7,怎么判断一个路径是不是符号链接?我试过用os.path.islink(),但是它总是返回假,说明要么不是符号链接,要么不支持。而我提供的路径肯定是符号链接,所以我在想是不是Windows不支持这个功能?那我该怎么办呢?

5 个回答

6

关于目录:

import os, ctypes
def IsSymlink(path):
    FILE_ATTRIBUTE_REPARSE_POINT = 0x0400
    return os.path.isdir(path) and (ctypes.windll.kernel32.GetFileAttributesW(unicode(path)) & FILE_ATTRIBUTE_REPARSE_POINT):

来源

7

这是我最后用来判断在Windows 7中一个文件或目录是否是链接的代码:

from subprocess import check_output, CalledProcessError
import os.path
import ctypes
def isLink(path):
    if os.path.exists(path):
        if os.path.isdir(path):
            FILE_ATTRIBUTE_REPARSE_POINT = 0x0400
            attributes = ctypes.windll.kernel32.GetFileAttributesW(unicode(path))
            return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) > 0
        else:
            command = ['dir', path]
            try:
                with open(os.devnull, 'w') as NULL_FILE:
                    o0 = check_output(command, stderr=NULL_FILE, shell=True)
            except CalledProcessError as e:
                print e.output
                return False
            o1 = [s.strip() for s in o0.split('\n')]
            if len(o1) < 6:
                return False
            else:
                return 'SYMLINK' in o1[5]
    else:
        return False

编辑:根据Zitrax和Annan的建议修改了代码

编辑:根据shioko的建议添加了包含语句

20

根本问题是你使用的Python版本太旧了。如果你想继续用2.x版本,那就无法享受到2010年初之后新增的功能。

其中一个新增的功能是处理NTFS的符号链接。这项功能是在2010年底的3.2版本中加入的。(详细信息可以查看3.23.12.7的源代码。)

在那之前,Python不处理NTFS符号链接的原因是直到2009年底才有这样的东西。(如果我没记错,支持是在6.0内核中加入的,但在Vista/2008上需要安装服务包才能使用;只有7/2008R2及更新版本才自带这个功能。而且,你还需要一个足够新的MSVCRT才能访问这个用户空间的支持,而Python有明确的政策,不会在小版本更新中升级到新的Visual Studio版本。)

代码没有被移植回2.x版本的原因是不会有2.8版本,像2.7.3(或2.7.4)这样的bug修复版本只会修复bug,不会添加新功能。

这个问题已经被报告为问题13143,计划的解决方案是修改2.7的文档,明确说明在Windows上islink总是返回False

所以,如果你想在Windows上读取NTFS符号链接,要么升级到Python 3.2及以上版本,要么就得自己使用win32apictypes等来实现。

或者,正如Martijn Pieters所建议的,干脆使用一个像jaraco.windows这样的第三方库来完成这个功能,或者借用他们的代码

或者,如果你真的想的话,可以从3.2的源代码中借用代码,并围绕它构建一个C扩展模块。如果你从ntpath追踪到os再到nt(实际上是posixmodule.c),我相信它的核心部分在于win32_xstat_implwin32_xstat_impl_w

撰写回答