0x01文章背景最近,笔者所在公司某业务系统存储接近极限,服务器很快无法运行,原因是业务系统A包含多个子系统A1、A2、A3……An,由于设计原因,这些子系统的中间存储文件都存放在同一个父目录下。唯一不同的是,不同子系统生成的文件名和文件夹名都是以这个系统名开头的。比如A1子系统生成的文件名都是A1xxxxxx,A2子系统生成的文件名都是A2xxxxx。现在我们要删除部分子系统的历史文件,以释放服务器空间。数十TB的数据存储在一起。手动删除肯定不会显示。它只能借助程序自动化来实现。你用什么?自然而然地,蟒蛇浮现在脑海中。其实对于简单删除文件的需求,我觉得不值得长篇大论,但是我遇到了一些特别有趣的问题和一些有趣的解决方案,所以想和大家分享一下,比如超长的删除windows系统下的文件,比如从ReadtheofficialEnglishdocumentstofindsolutions等,进入正题。0x02使用python删除文件使用python删除文件的方法有很多种,最直接方便的方法是调用内置函数:os.remove()删除文件os.rmdir()删除空文件夹shutil.rmtree()删除一个文件夹和文件夹下的所有内容(包括子目录和文件),也就是解决这个问题的方法,核心就是处理上面三个函数。回到我们遇到的问题,业务系统A包含多个子系统A1、A2、A3……An,这些子系统的中间存储文件由于设计原因,都存储在同一个父目录下,唯一的区别是,不同子系统生成的文件名和文件夹名均以该子系统名开头。比如A1子系统生成的文件命名方式是A1xxxxxx,A2子系统生成的文件名都是A2xxxxx。现在的目的是删除指定子系统产生的文件,保留其他子系统的文件。反汇编需求实际上解决了以下四个问题:1、如何删除一个文件?2、如何识别某个文件或文件夹是由某个子系统生成的?3、如何判断一个路径是文件还是目录?4、如何定位指定子系统生成的所有文件和文件夹?对于问题1,本节开头解释,使用python内置函数删除:os.remove("path")#删除指定文件os.rmdir("path")#删除一个空文件夹shutil.rmtree("path")#删除一个文件夹及其所有内容(包括子目录和文件)对于问题2,具体子系统生成的文件和文件夹的命名方式是固定的,比如A1子系统生成的文件名都是A1xxxxx,所以可以通过关键词匹配来识别。一种可能的方式是:ifkeywordsinfilepath:#如果文件名中包含关键字os.remove(filepath)#删除文件else:pass对于问题3,因为删除目录的方式与删除文件的方式不一致,需要tobedelete在判断路径是目录还是文件之前,根据其类型选择合适的删除方式。这个可以通过python中的**os.path.isdir()**等函数来判断,主要有以下几个函数:os.path.isdir("path")#returntrue是一个目录,false是一个文件os.path.isfile("path")#returntrue是一个文件,false是一个目录对于问题4,如何定位所有要删除的文件,这个问题其实是遍历指定目录下的文件的问题,也就是如何遍历指定目录下的所有文件夹和文件。对于这个问题,一般有两种解法,一种是深度优先遍历法,一种是广度优先遍历法。在这个例子中两种方法的效率是一样的,因为我们最终会遍历所有的文件。另外,幸好python太强大了,它的内置函数已经帮我们实现了一个广度优先的目录遍历方法,os.walk("path")方法,就是遍历path目录下的所有文件和文件夹,一个典型的用法如下:importospath="C:\\A\\"forroot,dirs,filesinos.walk(path):print(root)print(dirs)print(files)以上example其中,root代表当前遍历的路径,dirs代表当前路径下的所有子目录,files代表当前路径下的所有子文件。这样就可以遍历所有指定的目录了。问题分解,结合下面问题完成代码实现。最终的代码实现是:importosimportshutilpath="C:\\A\\"keyword="A1"forroot,dirs,filesinos.walk(path):fordirindirs:ifkeywordindir:rmpath=os.path.join(root,dir)print("Deletefolder:%s"%rmpath)shutil.rmtree(rmpath)forfileinfiles:ifkeywordinfile:rmpath=os.path.join(root,file)print("Deletefile:%s"%rmpath)os.remove(rmpath)通过广度优先方法遍历规范(os.walk())directory,一一判断目录下的所有子目录和文件是否满足关键字条件,满足则删除。运行效果是:貌似需求基本解决的很好,但是在实际测试中发现有些深层目录没有删除,删除目录的时候报错。错误描述如下:Unexpectederror:(
