近期,笔者所在公司的某业务系统的存储临近极限,服务器马上就要跑不动了,由于该业务系统A包含多个子系统A1、A2、A3 ... An,这些子系统的中间存储文件由于设计原因,都存储在同一个父级目录之内,唯一不同的是,不同子系统产生的文件和文件夹的名字都以该子系统名开始。如A1子系统产生的文件命名方式均为A1xxxxxx, A2子系统产生的文件名均为A2xxxxx。现在要删除其中一些子系统的历史文件,以释放服务器空间,几十T的数据,存放在一起,手动删除肯定不显示,只能借助程序自动化实现了,使用什么呢?自然想到了python。其实单纯删文件这一个需求我认为不值得长篇阔论,但是其中遇到了一些特殊有趣的问题和一些有意思的解决方案,所以想与诸位分享一下,比如windows系统下的超长文件删除, 如从阅读官方英文文档寻找解决方案等等,下面进入正题。
使用python删除文件有很多方式,最直接也是最方便的方式就是调用内建函数:
也就是,此问题的的解决方案,核心就是围绕上述三个函数打交道。转到我们遇到的问题,业务系统A包含多个子系统A1、A2、A3 ... An,这些子系统的中间存储文件由于设计原因,都存储在同一个父级目录之内,唯一不同的是,不同子系统产生的文件和文件夹的名字都以该子系统名开始。如A1子系统产生的文件命名方式均为A1xxxxxx, A2子系统产生的文件名均为A2xxxxx,现在的目的就是要在该删除指定子系统所产生的文件,保留其他子系统的文件。
将需求拆解下,实际上就是解决下列4个问题:
1.怎么删除一个文件?
2.怎样识别一个文件或文件夹是某个子系统产生的?
3.如何判断一个路径是文件还是目录?
4.如何定位所有指定的子系统产生的文件和文件夹?
对于问题1, 在本节开始就阐述过,使用 python 的内建函数进行删除即可:
关键意思如下:1.Windows API 提供的文件路径理论上最长是 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)
根据上一节,对python程序进一步进行改造,加入windows长文件名限制解除,最后的完美删除工具就成型了:
import os import shutil path = "C:A" keyword = "A1" # 获取目标路径的绝对路径,并在路径前加上?, # 以解除windows的文件长度限制 path = '\?' + os.path.abspath(path) for root, dirs, files in os.walk(path): for dir in dirs: if keyword in dir: rmpath = os.path.join(root, dir) print("删除文件夹: %s" % rmpath) shutil.rmtree(rmpath) for file in files: if keyword in file: rmpath = os.path.join(root, file) print("删除文件: %s" % rmpath) os.remove(rmpath)
虽然代码很短,只添加了一行,但是这一行,却完成了一个超级核心的任务,真可谓是灵魂一行啊,最后该工具中如在生产环境中发挥了其出色的作用,使服务器继续运转如飞了。
啰嗦的话就不多说了,说几点思考 :
1.遇到问题将问题进行分解,拆分成一个个小问题逐步击破 。
2.要善于阅读官方技术文档,有时候解决一个问题的核心可能很简单,代码可能也就一行两行,但是就是藏在某个角落,不仔细去阅读还真不一定找得出来 。
3.python是个好东西,要有将问题转化成使用python去解决的习惯,习惯成自然,python可能在工作中就发挥大作用了呢。
1.https://docs.microsoft.com/en-US/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd
2.https://stackoverflow.com/questions/6996603/how-to-delete-a-file-or-folder-in