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