shutil.rmtree在Windows上失败,提示“拒绝访问”

2024-05-14 00:00:17 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python中,在包含只读文件的文件夹上运行shutil.rmtree时,将打印以下异常:

 File "C:\Python26\lib\shutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:\Python26\lib\shutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:\Python26\lib\shutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:\Python26\lib\shutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:\Python26\lib\shutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:\Python26\lib\shutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:\Python26\lib\shutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:\Python26\lib\shutil.py", line 221, in rmtree
   onerror(os.remove, fullname, sys.exc_info())
 File "C:\Python26\lib\shutil.py", line 219, in rmtree
   os.remove(fullname)
WindowsError: [Error 5] Access is denied: 'build\\tcl\\tcl8.5\\msgs\\af.msg'

在“文件属性”对话框中,我注意到af.msg文件被设置为只读。

所以问题是:考虑到我的意图是在Windows上做一个相当于rm -rf build/的工作,解决这个问题的最简单的方法是什么?(不必使用第三方工具,如unxutils或cygwin,因为这段代码的目标是在安装了Python 2.6w/PyWin32的裸Windows安装上运行)


Tags: 文件inpyosliblineremovefile
3条回答

看看这个问题:

What user do python scripts run as in windows?

显然,答案是将文件/文件夹更改为非只读,然后将其删除。

下面是@Sridhar Ratnakumar在评论中提到的^{}中的onerror()处理程序:

def onerror(func, path, exc_info):
    """
    Error handler for ``shutil.rmtree``.

    If the error is due to an access error (read only file)
    it attempts to add write permission and then retries.

    If the error is for another reason it re-raises the error.

    Usage : ``shutil.rmtree(path, onerror=onerror)``
    """
    import stat
    if not os.access(path, os.W_OK):
        # Is the error an access error ?
        os.chmod(path, stat.S_IWUSR)
        func(path)
    else:
        raise

我想说,用os.walk实现您自己的rmtree,在尝试删除之前,通过对每个文件使用os.chmod来确保访问。

类似这样的东西(未经测试):

import os
import stat

def rmtree(top):
    for root, dirs, files in os.walk(top, topdown=False):
        for name in files:
            filename = os.path.join(root, name)
            os.chmod(filename, stat.S_IWUSR)
            os.remove(filename)
        for name in dirs:
            os.rmdir(os.path.join(root, name))
    os.rmdir(top)      

好吧,有标记的解决方案对我不起作用。。。而是这样做了:

os.system('rmdir /S /Q "{}"'.format(directory))

相关问题 更多 >