在Windows上使用Python的os.path.islink
在Windows 7上用Python 2.7,怎么判断一个路径是不是符号链接?我试过用os.path.islink()
,但是它总是返回假,说明要么不是符号链接,要么不支持。而我提供的路径肯定是符号链接,所以我在想是不是Windows不支持这个功能?那我该怎么办呢?
5 个回答
关于目录:
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):
这是我最后用来判断在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的建议添加了包含语句
根本问题是你使用的Python版本太旧了。如果你想继续用2.x版本,那就无法享受到2010年初之后新增的功能。
其中一个新增的功能是处理NTFS的符号链接。这项功能是在2010年底的3.2版本中加入的。(详细信息可以查看3.2、3.1和2.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及以上版本,要么就得自己使用win32api
、ctypes
等来实现。
或者,正如Martijn Pieters所建议的,干脆使用一个像jaraco.windows
这样的第三方库来完成这个功能,或者借用他们的代码。
或者,如果你真的想的话,可以从3.2的源代码中借用代码,并围绕它构建一个C扩展模块。如果你从ntpath
追踪到os
再到nt
(实际上是posixmodule.c
),我相信它的核心部分在于win32_xstat_impl
和win32_xstat_impl_w
。