如何使用Python在Windows中删除只读属性目录?

54

我有一个从版本控制目录复制而来的只读目录,该目录是锁定的。 enter image description here

当我尝试使用shutil.rmtree(TEST_OBJECTS_DIR)命令删除此目录时,我收到了以下错误消息。

WindowsError: [Error 5] Access is denied: 'C:\...\environment.txt'
  • 问:如何更改整个目录结构中所有内容的属性?
6个回答

86

如果您正在使用shutil.rmtree,您可以使用该函数的onerror成员来提供一个函数,该函数接受三个参数:函数、路径和异常信息。您可以使用此方法在删除树时将只读文件标记为可写。

import os, shutil, stat

def on_rm_error( func, path, exc_info):
    # path contains the path of the file that couldn't be removed
    # let's just assume that it's read-only and unlink it.
    os.chmod( path, stat.S_IWRITE )
    os.unlink( path )

shutil.rmtree( TEST_OBJECTS_DIR, onerror = on_rm_error )

公平地说,错误函数可能因各种原因而被调用。'func'参数可以告诉您是哪个函数“出错”了(os.rmdir()或os.remove())。您在这里所做的取决于您希望rmtree多么健壮。如果只是需要将文件标记为可写,您可以像我上面所做的那样操作。如果要更加小心谨慎(即确定目录无法删除还是在尝试删除文件时发生了共享冲突),则应该将适当的逻辑插入到on_rm_error()函数中。


3
很酷!这是更专注的方法。 - YOU
2
对我来说,这是唯一可行的方法,可以使用shutil.rmtree安全地删除.git文件夹(包括只读文件)和.git文件。 - DarthVader
或许值得知道的是,根据Python文档的描述:“注意:尽管Windows支持chmod()函数,但你只能使用它来设置文件的只读标志(通过stat.S_IWRITEstat.S_IREAD常量或相应的整数值)。其他所有位都会被忽略。” - undefined

16

没有经过测试,但应该是启用写入访问权限之类的东西。

import os, stat

os.chmod(ur"file_path_name", stat.S_IWRITE)

您可能需要结合os.walk来使所有文件都具有写入权限,例如:

for root, dirs, files in os.walk(ur'root_dir'):
    for fname in files:
        full_path = os.path.join(root, fname)
        os.chmod(full_path ,stat.S_IWRITE)

更多细节在这里:http://techarttiki.blogspot.com/2008/08/read-only-windows-files-with-python.html - payne

9

接受的答案几乎正确,但在只读子目录的情况下可能会失败。

该函数作为参数传递给rmtreeonerror处理程序。

我建议:

import os, shutil, stat

def remove_readonly(fn, path, excinfo):
    try:
        os.chmod(path, stat.S_IWRITE)
        fn(path)
    except Exception as exc:
        print("Skipped:", path, "because:\n", exc)

shutil.rmtree(TEST_OBJECTS_DIR, onerror=remove_readonly)

如果该函数再次失败,您可以查看原因并继续删除。

8
我所使用的方法是这样做的:
if os.path.exists(target) :
    subprocess.check_call(('attrib -R ' + target + '\\* /S').split())
    shutil.rmtree(target)

在任何人指责我之前,我知道这种写法非常不符合Python的规范,但它可能比上面更传统的答案更简单,并且一直很可靠。

我不确定关于目录的读写属性会发生什么情况。但这还没有成为问题。


此解决方案适用于Windows(只要存在attrib.exe),并且不需要外部Python模块。 - Nils Lindemann
解决方案非常棒,我发现它更加高效。 - Kewin
@Nils 到目前为止,这里提供的其他解决方案都不需要任何外部 Python 模块。编辑:好吧,我错过了 win32con 的东西。 - antred

5
import win32con, win32api,os

file='test.txt'

#make the file hidden
win32api.SetFileAttributes(file,win32con.FILE_ATTRIBUTE_HIDDEN)

#make the file read only
win32api.SetFileAttributes(file,win32con.FILE_ATTRIBUTE_READONLY)

#to force deletion of a file set it to normal
win32api.SetFileAttributes(file, win32con.FILE_ATTRIBUTE_NORMAL)
os.remove(file)

翻译自:http://code.activestate.com/recipes/303343-changing-file-attributes-on-windows/

在Windows上更改文件属性

这个Python脚本可以用来更改Windows文件的属性和时间戳。


import os
import time

# 设置要更改的文件路径
file_path = r'C:\example\file.txt'

# 获取当前时间戳
timestamp = time.time()

# 更改文件创建时间戳
os.utime(file_path, (timestamp, os.path.getatime(file_path)))

# 更改文件修改时间戳
os.utime(file_path, (os.path.getctime(file_path), timestamp))

# 更改文件访问时间戳
os.utime(file_path, (os.path.getatime(file_path), timestamp))

# 更改文件属性为只读
os.chmod(file_path, 0o400)

请注意,您可以将导入的数量减少到只有“win32file”。因此:win32file.SetFileAttributes(file, win32file.FILE_ATTRIBUTE_READONLY) - Colin Atkinson

1
您可以使用以下代码取消文件夹的只读属性:
import os, stat
from stat import *
import shutil
import fnmatch

file_name = r'<file path>'
os.chmod(file_name, stat.S_IWRITE)
os.remove(file_name)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接