尝试删除不为空的文件夹时,出现“访问被拒绝”错误。我尝试使用以下命令:os.remove("/folder_name")
。
删除/删除不为空的文件夹/目录的最有效方法是什么?
rm -rf
的行为看:stackoverflow.com/questions/814167/...
尝试删除不为空的文件夹时,出现“访问被拒绝”错误。我尝试使用以下命令:os.remove("/folder_name")
。
删除/删除不为空的文件夹/目录的最有效方法是什么?
rm -rf
的行为看:stackoverflow.com/questions/814167/...
Answers:
import shutil
shutil.rmtree('/folder_name')
根据设计,rmtree
在包含只读文件的文件夹树上失败。如果要删除该文件夹而不管它是否包含只读文件,请使用
shutil.rmtree('/folder_name', ignore_errors=True)
rmtree
,如果有只读文件会失败:stackoverflow.com/questions/2656322/...
从Python文档上os.walk()
:
# Delete everything reachable from the directory named in 'top',
# assuming there are no symbolic links.
# CAUTION: This is dangerous! For example, if top == '/', it
# could delete all your disk files.
import os
for root, dirs, files in os.walk(top, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
import shutil
shutil.rmtree(dest, ignore_errors=True)
ignore_errors=True
解决了问题。
onerror
参数代替ignore_errors
。这样,只读文件将被删除而不是被忽略。
rmtree()
方法都将被忽略。
本示例说明如何在Windows上删除目录树,其中某些文件的只读位已设置。它使用onerror回调清除只读位并重新尝试删除。任何后续故障都将传播。
import os, stat import shutil def remove_readonly(func, path, _): "Clear the readonly bit and reattempt the removal" os.chmod(path, stat.S_IWRITE) func(path) shutil.rmtree(directory, onerror=remove_readonly)
import os
import stat
import shutil
def errorRemoveReadonly(func, path, exc):
excvalue = exc[1]
if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
# change the file to be readable,writable,executable: 0777
os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
# retry
func(path)
else:
# raiseenter code here
shutil.rmtree(path, ignore_errors=False, onerror=errorRemoveReadonly)
如果设置了ignore_errors,错误将被忽略;否则,如果设置了onerror,则将使用参数(函数,路径,exc_info)来处理错误,其中func为os.listdir,os.remove或os.rmdir;path是导致该函数失败的参数。而exc_info是sys.exc_info()返回的元组。如果ignore_errors为false并且onerror为None,则会引发异常。在此处输入代码
根据kkubasik的回答,删除之前检查文件夹是否存在,更可靠
import shutil
def remove_folder(path):
# check if folder exists
if os.path.exists(path):
# remove if exists
shutil.rmtree(path)
else:
# throw your exception to handle this special scenario
raise XXError("your exception")
remove_folder("/folder_name")
如果您确定要删除整个目录树,并且不再对目录内容感兴趣,那么爬网整个目录树是愚蠢的……只需从python调用本机OS命令即可。它将更快,更有效且内存消耗更少。
RMDIR c:\blah /s /q
或* nix
rm -rf /home/whatever
在python中,代码看起来像..
import sys
import os
mswindows = (sys.platform == "win32")
def getstatusoutput(cmd):
"""Return (status, output) of executing cmd in a shell."""
if not mswindows:
return commands.getstatusoutput(cmd)
pipe = os.popen(cmd + ' 2>&1', 'r')
text = pipe.read()
sts = pipe.close()
if sts is None: sts = 0
if text[-1:] == '\n': text = text[:-1]
return sts, text
def deleteDir(path):
"""deletes the path entirely"""
if mswindows:
cmd = "RMDIR "+ path +" /s /q"
else:
cmd = "rm -rf "+path
result = getstatusoutput(cmd)
if(result[0]!=0):
raise RuntimeError(result[1])
shutil.rmdir
是使您与操作系统类型隔离。
只需一些python 3.5选项即可完成上述答案。(我很想在这里找到他们)。
import os
import shutil
from send2trash import send2trash # (shutil delete permanently)
删除文件夹(如果为空)
root = r"C:\Users\Me\Desktop\test"
for dir, subdirs, files in os.walk(root):
if subdirs == [] and files == []:
send2trash(dir)
print(dir, ": folder removed")
如果包含此文件的文件夹也删除
elif subdirs == [] and len(files) == 1: # if contains no sub folder and only 1 file
if files[0]== "desktop.ini" or:
send2trash(dir)
print(dir, ": folder removed")
else:
print(dir)
如果仅包含.srt或.txt文件,则删除文件夹
elif subdirs == []: #if dir doesn’t contains subdirectory
ext = (".srt", ".txt")
contains_other_ext=0
for file in files:
if not file.endswith(ext):
contains_other_ext=True
if contains_other_ext== 0:
send2trash(dir)
print(dir, ": dir deleted")
删除小于400kb的文件夹:
def get_tree_size(path):
"""Return total size of files in given path and subdirs."""
total = 0
for entry in os.scandir(path):
if entry.is_dir(follow_symlinks=False):
total += get_tree_size(entry.path)
else:
total += entry.stat(follow_symlinks=False).st_size
return total
for dir, subdirs, files in os.walk(root):
If get_tree_size(dir) < 400000: # ≈ 400kb
send2trash(dir)
print(dir, "dir deleted")
if files[0]== "desktop.ini" or:
我想添加“纯路径库”方法:
from pathlib import Path
from typing import Union
def del_dir(target: Union[Path, str], only_if_empty: bool = False):
target = Path(target).expanduser()
assert target.is_dir()
for p in sorted(target.glob('**/*'), reverse=True):
if not p.exists():
continue
p.chmod(0o666)
if p.is_dir():
p.rmdir()
else:
if only_if_empty:
raise RuntimeError(f'{p.parent} is not empty!')
p.unlink()
target.rmdir()
这取决于Path
可排序的事实,较长的路径总是会在较短的路径之后排序,就像str
。因此,目录将位于文件之前。如果我们反转排序,那么文件将位于它们各自的容器之前,因此我们可以简单地一遍一遍地取消链接/ rmdir文件。
优点:
pathlib
Python 3.6 中的承诺;上述所有操作都说不能在Windows上运行)def deleteDir(dirPath):
deleteFiles = []
deleteDirs = []
for root, dirs, files in os.walk(dirPath):
for f in files:
deleteFiles.append(os.path.join(root, f))
for d in dirs:
deleteDirs.append(os.path.join(root, d))
for f in deleteFiles:
os.remove(f)
for d in deleteDirs:
os.rmdir(d)
os.rmdir(dirPath)
如果您不想使用该shutil
模块,则可以使用该os
模块。
from os import listdir, rmdir, remove
for i in listdir(directoryToRemove):
os.remove(os.path.join(directoryToRemove, i))
rmdir(directoryToRemove) # Now the directory is empty of files
os.remove
无法删除目录,因此OsError
如果directoryToRemove
包含子目录,则会引起此问题。
十年后,使用Python 3.7和Linux仍然有不同的方法:
import subprocess
from pathlib import Path
#using pathlib.Path
path = Path('/path/to/your/dir')
subprocess.run(["rm", "-rf", str(path)])
#using strings
path = "/path/to/your/dir"
subprocess.run(["rm", "-rf", path])
本质上,它是使用Python的子进程模块来运行bash脚本,$ rm -rf '/path/to/your/dir
就像使用终端来完成相同的任务一样。它不是完全Python,但是可以完成。
我包含该pathlib.Path
示例的原因是因为根据我的经验,在处理许多变化的路径时,它非常有用。导入pathlib.Path
模块并将最终结果转换为字符串的额外步骤通常对我来说是较低的开发时间成本。如果Path.rmdir()
带有arg选项来显式处理非空dirs ,将很方便。
rmtree
和这类隐藏文件夹的问题.vscode
。该文件夹被检测为文本文件,错误告诉我该文件曾经busy
且无法删除。
即使一个文件夹可能不存在,也要删除该文件夹(避免使用Charles Chow的竞价条件),但在其他情况出错(例如权限问题,磁盘读取错误,该文件不是目录)时仍然存在错误
对于Python 3.x:
import shutil
def ignore_absent_file(func, path, exc_inf):
except_instance = exc_inf[1]
if isinstance(except_instance, FileNotFoundError):
return
raise except_instance
shutil.rmtree(dir_to_delete, onerror=ignore_absent_file)
Python 2.7代码几乎相同:
import shutil
import errno
def ignore_absent_file(func, path, exc_inf):
except_instance = exc_inf[1]
if isinstance(except_instance, OSError) and \
except_instance.errno == errno.ENOENT:
return
raise except_instance
shutil.rmtree(dir_to_delete, onerror=ignore_absent_file)
使用os.walk,我将提出包含3个单行Python调用的解决方案:
python -c "import sys; import os; [os.chmod(os.path.join(rs,d), 0o777) for rs,ds,fs in os.walk(_path_) for d in ds]"
python -c "import sys; import os; [os.chmod(os.path.join(rs,f), 0o777) for rs,ds,fs in os.walk(_path_) for f in fs]"
python -c "import os; import shutil; shutil.rmtree(_path_, ignore_errors=False)"
第一个脚本chmod的所有子目录,第二个脚本chmod的所有文件。然后,第三个脚本将无障碍地删除所有内容。
我已经在Jenkins作业中的“ Shell脚本”中对此进行了测试(我不想将新的Python脚本存储到SCM中,这就是为什么要搜索单行解决方案的原因),并且它适用于Linux和Windows。
pathlib
,您可以将前两个步骤组合为一个:[p.chmod(0o666) for p in pathlib.Path(_path_).glob("**/*")]
为了简单起见,可以使用os.system命令:
import os
os.system("rm -rf dirname")
显而易见,它实际上调用系统终端来完成此任务。
对于Windows,如果目录不为空,并且您具有只读文件,或者出现诸如
Access is denied
The process cannot access the file because it is being used by another process
尝试这个, os.system('rmdir /S /Q "{}"'.format(directory))
rm -rf
在Linux / Mac中等效。