2013-03-06 46 views
11

在Windows 7与Python 2.7如何检测路径是否是符号链接? 这不起作用,它说如果返回false或不支持,我提供的路径肯定是一个符号链接,所以我假设它不支持在Windows上?我能做什么?os.path.islink与Python的窗口

+3

[这](http://bugs.python.org/issue13143)可以provid e一些帮助。 – crayzeewulf 2013-03-06 21:46:06

+2

查看['jaraco.windows'包](https://bitbucket.org/jaraco/jaraco.windows/src/default/jaraco/windows/filesystem/__init__.py);它必须使用'ctypes'来支持这一点。 Python 3.2 *确实*支持Windows符号链接。 – 2013-03-06 21:46:34

回答

19

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

其中一个功能是处理NTFS符号链接。在3.2中加入在2010年底该功能(见3.23.1,并且2.7源的详细信息。)

原因的Python没有处理NTFS符号链接在此之前是没有这样的事,直到2009年年底。 (IIRC,支持包含在6.0内核中,但用户空间支持需要Vista/2008上的Service Pack;只有7/2008R2和更新的内置内置内置。另外,您需要一个足够新的MSVCRT才能访问用户级支持,而且Python有明确的政策,不会在次要版本中升级到新的Visual Studio版本。)

代码未被移植回2.x的原因是that there will never be a 2.8,并且错误修复版本像2.7。 3(或2.7.4)不会得到ne w功能,只有错误修复。

这已报告为issue 13143,并且打算修复此问题的目的是更改2.7文档以阐明在Windows上始终返回False

因此,如果您想在Windows下阅读NTFS符号链接,请升级到Python 3.2+,或者您必须使用win32apictypes等自己完成。

或者,正如Martijn Pieters所建议的那样,您可以使用像jaraco.windows这样的第三方库和/或借用their code。或者,如果你真的想要,可以从3.2源代码中借用代码并在其周围构建一个C扩展模组。如果你从ntpathosnt(实际上是posixmodule.c),我相信它的胆量在win32_xstat_impl and win32_xstat_impl_w

+0

谁低估,谨慎解释为什么? – abarnert 2013-03-06 22:28:05

+0

太棒了!谢谢你abarnert – user391986 2013-03-06 23:04:23

+0

你必须误导。重分析点确实存在于Windows NT 5(Windows 2000)与NTFS 3.0。它功能强大。 python的实现简直是懒惰或者也是错误的。 – 2015-01-15 05:10:32

5

这是我结束了使用,以确定是否一个文件或目录是Windows 7的链接:

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和安南

+0

当文件不存在时,值得从'check_output'捕获CalledProcessError's。你也可以通过'stderr = subprocess.PIPE'来隐藏输出到stdin的错误。这个解决方案真的很不方便,但比其他答案更可行。 – Annan 2015-05-07 22:17:31

+0

此答案无法检查目录是否为链接,因此dir命令只会列出内容。 – Zitrax 2016-03-10 11:46:00

+0

@Zitrax:'dir/al“路径*”'作品 – 2016-12-09 11:11:33

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): 

Source

+0

源代码已死 – thatsIch 2018-02-15 10:58:51

+0

@thatsIch已更新指向archive.org缓存的链接。 – Zitrax 2018-02-15 11:22:59

+0

比较你缺少return语句的来源。你可以检查结果是否> 0否则结果是1024 – thatsIch 2018-02-15 12:32:57