翼度科技»论坛 编程开发 python 查看内容

python移除/删除非空文件夹/目录的最有效方法是什么?

11

主题

11

帖子

33

积分

新手上路

Rank: 1

积分
33
1.标准库参考:shutil.rmtree。

根据设计,rmtree在包含只读文件的文件夹树上失败。如果要删除文件夹,不管它是否包含只读文件,请使用
  1. import shutil
  2. shutil.rmtree('/folder_name', ignore_errors=True)
复制代码
2.从os.walk()上的python文档中:
  1. # Delete everything reachable from the directory named in 'top',
  2. # assuming there are no symbolic links.
  3. # CAUTION:  This is dangerous!  For example, if top == '/', it
  4. # could delete all your disk files.
  5. import os
  6. for root, dirs, files in os.walk(top, topdown=False):
  7.     for name in files:
  8.         os.remove(os.path.join(root, name))
  9.     for name in dirs:
  10.         os.rmdir(os.path.join(root, name))
复制代码
3.从python 3.4可以使用:
  1. import pathlib
  2. def delete_folder(pth) :
  3.     for sub in pth.iterdir() :
  4.         if sub.is_dir() :
  5.             delete_folder(sub)
  6.         else :
  7.             sub.unlink()
  8.     pth.rmdir() # if you just want to delete dir content, remove this line
复制代码
其中pth是pathlib.Path实例。很好,但可能不是最快的。
  1. import os
  2. import stat
  3. import shutil
  4. def errorRemoveReadonly(func, path, exc):
  5.     excvalue = exc[1]
  6.     if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
  7.         # change the file to be readable,writable,executable: 0777
  8.         os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)  
  9.         # retry
  10.         func(path)
  11.     else:
  12.         # raiseenter code here
  13. shutil.rmtree(path, ignore_errors=False, onerror=errorRemoveReadonly)
复制代码
如果设置了ignore_errors,则忽略错误;否则,如果设置了onerror,则调用它以使用参数(func、path、exc_info)处理错误,其中func是os.listdir、os.remove或os.rmdir;path是导致函数失败的函数的参数;exc_info是sys.exc_info()返回的元组。如果"忽略错误"为"假",而"OnError"为"无",则会引发异常。请在此处输入代码。
只需一些python3.5选项就可以完成上面的答案
删除空文件夹
  1. import os
  2. import shutil
  3. from send2trash import send2trash # (shutil delete permanently)
  4. root = r"C:\Users\Me\Desktop\test"  
  5. for dir, subdirs, files in os.walk(root):  
  6.     if subdirs == [] and files == []:
  7.            send2trash(dir)
  8.            print(dir,": folder removed")
  9.    # 如果文件夹包含此文件,请同时删除它
  10.    elif subdirs == [] and len(files) == 1: # if contains no sub folder and only 1 file
  11.         if files[0]=="desktop.ini" or:  
  12.             send2trash(dir)
  13.             print(dir,": folder removed")
  14.         else:
  15.             print(dir)
  16.     #删除仅包含.srt或.txt文件的文件夹
  17.     elif subdirs == []: #if dir doesn’t contains subdirectory
  18.         ext = (".srt",".txt")
  19.         contains_other_ext=0
  20.         for file in files:
  21.             if not file.endswith(ext):  
  22.                 contains_other_ext=True
  23.         if contains_other_ext== 0:
  24.                 send2trash(dir)
  25.                 print(dir,": dir deleted")   
复制代码
如果文件夹大小小于400KB,则删除该文件夹:
  1. def get_tree_size(path):
  2.    """Return total size of files in given path and subdirs."""
  3.     total = 0
  4.     for entry in os.scandir(path):
  5.         if entry.is_dir(follow_symlinks=False):
  6.             total += get_tree_size(entry.path)
  7.         else:
  8.             total += entry.stat(follow_symlinks=False).st_size
  9.     return total
  10. for dir, subdirs, files in os.walk(root):  
  11.     If get_tree_size(dir) < 400000:  # ≈ 400kb
  12.         send2trash(dir)
  13.     print(dir,"dir deleted")
复制代码
如果您确定要删除整个目录树,并且对目录的内容不再感兴趣,那么对整个目录树进行爬行是愚蠢的…只需从python调用本机操作系统命令即可。它将更快、更高效,而且内存消耗更少。
  1. RMDIR c:\blah /s /q
复制代码
或* nix
  1. rm -rf /home/whatever
复制代码
在Python中,代码看起来像..
  1. import sys
  2. import os
  3. mswindows = (sys.platform =="win32")
  4. def getstatusoutput(cmd):
  5.    """Return (status, output) of executing cmd in a shell."""
  6.     if not mswindows:
  7.         return commands.getstatusoutput(cmd)
  8.     pipe = os.popen(cmd + ' 2>&1', 'r')
  9.     text = pipe.read()
  10.     sts = pipe.close()
  11.     if sts is None: sts = 0
  12.     if text[-1:] == '
  13. ': text = text[:-1]
  14.     return sts, text
  15. def deleteDir(path):
  16.    """deletes the path entirely"""
  17.     if mswindows:
  18.         cmd ="RMDIR"+ path +" /s /q"
  19.     else:
  20.         cmd ="rm -rf"+path
  21.     result = getstatusoutput(cmd)
  22.     if(result[0]!=0):
  23.         raise RuntimeError(result[1])
复制代码
从docs.python.org:
  1. This example shows how to remove a directory tree on Windows where
  2. some of the files have their read-only bit set. It uses the onerror
  3. callback to clear the readonly bit and reattempt the remove.
复制代码
  1. import os, stat
  2. import shutil
  3. def remove_readonly(func, path, _):
  4.    "Clear the readonly bit and reattempt the removal"
  5.     os.chmod(path, stat.S_IWRITE)
  6.     func(path)
  7. shutil.rmtree(directory, onerror=remove_readonly)
复制代码
在删除之前检查文件夹是否存在,这样更可靠。
  1. import shutil
  2. def remove_folder(path):
  3.     # check if folder exists
  4.     if os.path.exists(path):
  5.          # remove if exists
  6.          shutil.rmtree(path)
  7.     else:
  8.          # throw your exception to handle this special scenario
  9.          raise XXError("your exception")
  10. remove_folder("/folder_name")
复制代码
如果您不想使用shutil模块,可以只使用os模块。
  1. from os import listdir, rmdir, remove
  2. for i in listdir(directoryToRemove):
  3.     os.remove(os.path.join(directoryToRemove, i))
  4. rmdir(directoryToRemove) # Now the directory is empty of files
  5. def deleteDir(dirPath):
  6.     deleteFiles = []
  7.     deleteDirs = []
  8.     for root, dirs, files in os.walk(dirPath):
  9.         for f in files:
  10.             deleteFiles.append(os.path.join(root, f))
  11.         for d in dirs:
  12.             deleteDirs.append(os.path.join(root, d))
  13.     for f in deleteFiles:
  14.         os.remove(f)
  15.     for d in deleteDirs:
  16.         os.rmdir(d)
  17.     os.rmdir(dirPath)
复制代码
为了简单起见,可以使用os.system命令:
  1. import os
  2. os.system("rm -rf dirname")
复制代码
很明显,它实际上调用系统终端来完成这个任务。
删除一个文件夹,即使它可能不存在(避免了Charles Chow的答案中的竞争条件),但当其他事情出错时仍有错误(例如权限问题、磁盘读取错误、文件不是目录)
对于Python 3 .x:
  1. import shutil
  2. def ignore_absent_file(func, path, exc_inf):
  3.     except_instance = exc_inf[1]
  4.     if isinstance(except_instance, FileNotFoundError):
  5.         return
  6.     raise except_instance
  7. shutil.rmtree(dir_to_delete, onerror=ignore_absent_file)
复制代码
通过os.walk,我将提出由3个一行程序python调用组成的解决方案:
  1. 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]"
  2. 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]"
  3. python -c"import os; import shutil; shutil.rmtree(_path_, ignore_errors=False)"
复制代码
第一个脚本chmod的所有子目录,第二个脚本chmod的所有文件。然后,第三个脚本会毫无障碍地删除所有内容。
我在Jenkins工作中的"shell脚本"中对此进行了测试(我不想将新的python脚本存储到SCM中,这就是为什么搜索单行解决方案),它适用于Linux和Windows。
使用python 3.7和linux仍然有不同的方法:
  1. import subprocess
  2. from pathlib import Path
  3. #学习中遇到问题没人解答?小编创建了一个Python学习交流群:711312441
  4. #using pathlib.Path
  5. path = Path('/path/to/your/dir')
  6. subprocess.run(["rm","-rf", str(path)])
  7. #using strings
  8. path ="/path/to/your/dir"
  9. subprocess.run(["rm","-rf", path])
复制代码
本质上,它使用python的子进程模块来运行bash脚本$ rm -rf '/path/to/your/dir,就好像使用终端来完成相同的任务一样。它不是完全的python,但它可以完成。
我将pathlib.Path示例包括在内的原因是,根据我的经验,它在处理许多变化的路径时非常有用。导入pathlib.Path模块并将最终结果转换为字符串的额外步骤对于我的开发时间来说通常会降低成本。如果Path.rmdir()带有一个arg选项来显式处理非空的dir,那就方便了。
对于Windows,如果目录不是空的,并且您有只读文件,或者收到如下错误:
  1. Access is denied
  2. The process cannot access the file because it is being used by another process
复制代码
试试这个,os.system('rmdir /S /Q"{}"'.format(directory))。
它相当于Linux/Mac中的rm -rf。
我找到了一种非常简单的方法来删除Windows操作系统上的任何文件夹(甚至不是空的)或文件。
  1. os.system('powershell.exe  rmdir -r D:\workspace\Branches\*%s* -Force' %CANDIDATE_BRANCH)
复制代码
来源:https://www.cnblogs.com/python1111/p/18040856
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具