12

在带有 Python 2.7 的 Windows 7 上,如何检测路径是否为符号链接?这不起作用os.path.islink(),它说如果 false 或不支持它会返回 false 并且我提供的路径绝对是符号链接,所以我假设它在 windows 上不受支持?我能做些什么?

4

5 回答 5

20

根本问题是您使用的 Python 版本太旧。如果您想坚持使用 2.x,您将无法利用 2010 年初之后添加的新功能。

其中一项功能是处理 NTFS 符号链接。该功能于 2010 年底在 3.2 中添加。(有关详细信息,请参阅3.23.12.7源代码。)

在那之前 Python 没有处理 NTFS 符号链接的原因是直到 2009 年底才出现这种情况。(IIRC,支持包含在 6.0 内核中,但用户态支持需要 Vista/2008 上的服务包;只有 7/2008R2 和较新的内置了它。另外,您需要一个足够新的 MSVCRT 才能访问该用户区支持,并且 Python 有一个明确的政策,即在次要版本中不升级到新的 Visual Studio 版本。)

代码没有移植回 2.x 的原因是永远不会有 2.8,并且像 2.7.3(或 2.7.4)这样的错误修复版本没有新功能,只有错误修复。

这已报告为问题 13143,并且预期的修复是更改 2.7 文档以澄清islink始终False在 Windows 上返回。

所以,如果你想在 Windows 下阅读 NTFS 符号链接,要么升级到 Python 3.2+,要么你必须使用win32api,ctypes等自行完成。

或者,正如 Martijn Pieters 所建议的那样,与其自己做,不如使用第三方库jaraco.windows和/或借用他们的代码

或者,如果您真的愿意,可以从 3.2 源代码中借用代码并围绕它构建一个 C 扩展模块。如果您从ntpathto 到osto nt(实际上是posixmodule.c),我相信它的胆量在win32_xstat_implandwin32_xstat_impl_w中。

于 2013-03-06T22:05:39.963 回答
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 的建议添加了包含语句

于 2014-11-26T23:51:09.883 回答
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):

资源

于 2016-03-10T11:55:51.867 回答
2

也可以使用 pywin32 模块:GetFileAttributeswin32api子模块和模块FILE_ATTRIBUTE_REPARSE_POINT中都有win32con。例如,要测试给定路径是否是目录的符号链接,代码变为:

import os
import win32api
import win32con

def is_directory_symlink(path):
    return bool(os.path.isdir(path) 
                and (win32api.GetFileAttributes(path) &
                     win32con.FILE_ATTRIBUTE_REPARSE_POINT))

如果使用 Python 2 并且路径可能包含非 ascii 字符,则GetFileAttributes需要 unicode 字符串。但是,简单地使用unicode(path)通常会失败:您应该测试 ifpath是 a str,如果是,则使用它的decode方法。

于 2018-08-10T15:25:28.380 回答
-2

只为我使用if file[-4:len(file)] != ".lnk":作品

于 2018-08-09T13:17:28.127 回答