迅闻网
让更多人看到你

手把手运用 python 删除 windows 下的长路径文件

0x01文章背景
近期,笔者所在公司的某事务体系的存储临近极限,服务器立刻就要跑不动了,因为该事务体系A包括多个子体系A1、A2、A3…An,这些子体系的中心存储文件因为设计原因,都存储在同一个父级目录之内,仅有不同的是,不同子体系发生的文件和文件夹的姓名都以该子体系名开端。如A1子体系发生的文件命名办法均为A1xxxxxx,A2子体系发生的文件名均为A2xxxxx。现在要删去其间一些子体系的前史文件,以开释服务器空间,几十T的数据,存放在一起,手动删去肯定不显现,只能借助程序自动化完成了,运用什么呢?天然想到了python。其实单纯删文件这一个需求我以为不值得长篇阔论,可是其间遇到了一些特别风趣的问题和一些有意思的处理方案,所以想与诸位共享一下,比方windows体系下的超长文件删去,如从阅览官方英文文档寻觅处理方案等等,下面进入正题。
0x02运用python删去文件
运用python删去文件有很多办法,最直接也是最方便的办法便是调用内建函数:
os.remove()删去文件
os.rmdir()删去一个空文件夹
shutil.rmtree()删去一个文件夹及该文件夹下一切内容(包括子目录及文件)
也便是,此问题的的处理方案,中心便是围绕上述三个函数打交道。转到咱们遇到的问题,事务体系A包括多个子体系A1、A2、A3…An,这些子体系的中心存储文件因为设计原因,都存储在同一个父级目录之内,仅有不同的是,不同子体系发生的文件和文件夹的姓名都以该子体系名开端。如A1子体系发生的文件命名办法均为A1xxxxxx,A2子体系发生的文件名均为A2xxxxx,现在的目的便是要在该删去指定子体系所发生的文件,保存其他子体系的文件。
将需求拆解下,实际上便是处理下列4个问题:1、怎样删去一个文件?2、怎样辨认一个文件或文件夹是某个子体系发生的?3、怎么判别一个途径是文件仍是目录?4、怎么定位一切指定的子体系发生的文件和文件夹?
关于问题1,在本节开端就阐述过,运用python的内建函数进行删去即可:
os.remove(“path”)#删去指定文件os.rmdir(“path”)#删去一个空文件夹shutil.rmtree(“path”)#删去一个文件夹及该文件夹下一切内容(包括子目录及文件)
关于问题2,因为特定子体系发生的文件和文件夹的命名办法都是固定的形式,如A1子体系发生的文件名均为A1xxxxx,故可经过关键字匹配的办法进行辨认。一种或许的办法为:
ifkeywordsinfilepath:#假如文件名包括关键字keywordsos.remove(filepath)#删去文件else:
pass
关于问题3,因为删去目录和删去文件的办法不共同,故需要在删去前判别一个途径是目录仍是文件,根据其类型挑选合适的删去办法,这个在python中能够运用**os.path.isdir()**之类的函数进行判别,主要是下列函数:
os.path.isdir(“path”)#回来true则为目录,false则为文件os.path.isfile(“path”)#回来true则为文件,false则为目录
关于问题4,怎么定位一切要删去的文件,这个问题实际上便是一个指定目录文件遍历的问题,即怎么遍历一个指定目录的一切文件夹及文件。关于这个问题,一般有两种处理方案,一是深度优先遍历办法,一是广度优先遍历办法,两种办法在本例中效率是共同的,因为咱们终究都要遍历一切的文件。别的,幸运的是,python实在是过于强壮,其内建的函数现已协助咱们完成了一个广度优先目录遍历办法,及os.walk(“path”)办法,该办法便是遍历path目录下的一切文件及文件夹,一个典型的用法如下:

python
importos
path=”C:\\A\\”forroot,dirs,filesinos.walk(path):
print(root)
print(dirs)
print(files)
上例中,root代表当时遍历到的途径,dirs表示当时途径下一切的子目录,files表示当时途径下的一切子文件。经过这种办法就能全部遍历指定目录了。
问题都分解开了,下面将问题组合一下就完成代码完成.
终究的代码完成为:
importos
importshutil
path=”C:\\A\\”keyword=”A1″forroot,dirs,filesinos.walk(path):
fordirindirs:
ifkeywordindir:
rmpath=os.path.join(root,dir)
print(“删去文件夹:%s”%rmpath)
shutil.rmtree(rmpath)
forfileinfiles:
ifkeywordinfile:
rmpath=os.path.join(root,file)
print(“删去文件:%s”%rmpath)
os.remove(rmpath)
即经过广度优先办法(os.walk())遍历指定目录,逐个判别该目录下一切子目录和文件是否满足关键字条件,满足就删去。
运转效果为:
看似需求到此基本上就很好的处理了,可是实际测试中发现有的很深的目录却没有删去,删去该目录时报了一个错,过错描绘如下:
Unexpectederror:(<type’exceptions.WindowsError’>,WindowsError(3,’Thesystemcannotfindthepathspecified’),<tracebackobjectat0x0000000002714F88>)
大致意思便是python找不到这个途径,可是为什么呢?为此,我继续进行一番材料查询,后来大致定位了是因为文件途径过长导致的,是因为windows体系用户态的默许途径长度不能超越256个字节导致的。可是官方说256个字节是最长,但为何能创立超越256的呢,所以已然能创立,那就一定能删去,可是需要一些办法,经过一番学习,找到了好几种办法,下面介绍其间一种最为实用的办法,别的几个比方运用紧缩软件紧缩后删去(百度知道的结果)合适手动但不合适编程处理。这个办法在下一节中继续叙述。
0x03windows文件体系关于长途径文件的相关界说
为处理windows下的长文件删去的问题,最为权威的材料莫过于windows官方的描绘,我阅览了微软关于文件名长度的这一块的界说及阐明,找到处理方案,微软的原文如下:
关键意思如下:1、WindowsAPI供给的文件途径理论上最长是32767个字节,普通状态下给用户运用是不超越256个字符,说是为了运用户操作愈加方便。这儿不得不吐槽一下了,的确操作方便了,可是方便的一起也或许带来不便,明明界说了32767这么长的字节,只给用256,未免太抠搜了一点
2、用户假如想要打破这个长度约束,能够经过一个特别办法告知windows体系自己想要运用超长文件,这个特别的办法便是在绝对途径前加上**”\?”**字符串。
3、这篇文档后面还有描绘在windows10以后怎么经过注册表的办法触摸文件名长度约束,这儿就没有截图了,因为不通用,win7怎样办呢?有兴趣的同学能够检查其原文链接阅览:https://docs.microsoft.com/en-US/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd
好了,看到这,处理办法呼之欲出,其实简略得不能太简略,直接在绝对途径前加上一个”\?”即可:
#获取方针途径的绝对途径,并在途径前加上\\?\,#以免除windows的文件长度约束path=’\\\\?\\’+os.path.abspath(path)
0x04改造python程序,删去长途径文件
根据上一节,对python程序进一步进行改造,参加windows长文件名约束免除,最终的完美删去东西就成型了:
importosimportshutil
path=”C:\\A\\”keyword=”A1″#获取方针途径的绝对途径,并在途径前加上\\?\,#以免除windows的文件长度约束path=’\\\\?\\’+os.path.abspath(path)forroot,dirs,filesinos.walk(path):
fordirindirs:
ifkeywordindir:
rmpath=os.path.join(root,dir)
print(“删去文件夹:%s”%rmpath)
shutil.rmtree(rmpath)
forfileinfiles:
ifkeywordinfile:
rmpath=os.path.join(root,file)
print(“删去文件:%s”%rmpath)
os.remove(rmpath)
尽管代码很短,只添加了一行,可是这一行,却完成了一个超级中心的任务,真可谓是魂灵一行啊,最终该东西中如在生产环境中发挥了其出色的效果,使服务器继续运转如飞了。
0x04总结思考
烦琐的话就不多说了,说几点思考
1、遇到问题将问题进行分解,拆分成一个个小问题逐渐击破
2、要善于阅览官方技能文档,有时候处理一个问题的中心或许很简略,代码或许也就一行两行,可是便是藏在某个旮旯,不细心去阅览还真不一定找得出来
3、python是个好东西,要有将问题转化成运用python去处理的习气,习气成天然,python或许在作业中就发挥大效果了呢。

未经允许不得转载:迅闻网 » 手把手运用 python 删除 windows 下的长路径文件
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

迅闻网-让更多人看到你

登录/注册返回首页