一、需求分析
1. 删除前3天的文件
2.如果目录为空,也一并删除掉
如果使用shell脚本,一条命令就搞定了。干啥还要用python?
1. 因为需要记录一些日志,使用shell不好实现
2. 作为一名python开发,能用python实现,岂不增长你的技术,不是吗?
二、相关知识点
1. 获取文件修改时间
在os模块中,有一个方法os.path.getmtime(),可以获取文件修改时间。
例如:
import os ret = os.path.getmtime('test.docx') print(ret)
执行输出:
1542704403.1820524
它的返回结果是一个时间戳
2. 获取前3天时间
在time模块中,不好实现获取前3天的时间。但是datetime模块是可以的!
import datetime # 获取当前时间 today = datetime.datetime.now() # 计算偏移量,前3天 offset = datetime.timedelta(days=-3) # 获取想要的日期的时间,即前3天时间 re_date = (today + offset) print(today.strftime('%Y-%m-%d')) # 当前日期 print(re_date.strftime('%Y-%m-%d')) # 前3天日期
执行输出:
2018-11-21 2018-11-18
时间比较
那么问题来了,上面的文件修改时间是一个时间戳格式。而这里是日期,如何比较?
只要格式统一就可以了,将日期转换为时间戳,使用time.mktime()方法
import time import datetime # 获取当前时间 today = datetime.datetime.now() # 计算偏移量,前3天 offset = datetime.timedelta(days=-3) # 获取想要的日期的时间,即前3天时间 re_date = (today + offset) # 前3天时间转换为时间戳 re_date_unix = time.mktime(re_date.timetuple()) # print(today.strftime('%Y-%m-%d')) # 当前日期 # print(re_date.strftime('%Y-%m-%d')) # 前3天日期 print(re_date_unix) # 前3天日期的时间戳格式
执行输出:
1542523307.0
开始正式比较,test.docx的文件时间是否需要删除
#!/usr/bin/env python # coding: utf-8 import os import time import datetime # 获取当前时间 today = datetime.datetime.now() # 计算偏移量,前3天 offset = datetime.timedelta(days=-3) # 获取想要的日期的时间,即前3天时间 re_date = (today + offset) # 前3天时间转换为时间戳 re_date_unix = time.mktime(re_date.timetuple()) print("当前日期",today.strftime('%Y-%m-%d')) # 当前日期 print("前3天日期",re_date.strftime('%Y-%m-%d')) # 前3天日期 file_time = os.path.getmtime('test.docx') # 文件修改时间 timeArray = time.localtime(file_time) # 时间戳->结构化时间 otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray) #格式化时间 print("文件修改时间",otherStyleTime) if file_time <= re_date_unix: print("已经超过3天,需要删除") else: print("未超过3天,无需处理!")
执行输出:
当前日期 2018-11-21 前3天日期 2018-11-18 文件修改时间 2018-11-20 17:00:03 未超过3天,无需处理!
3. 空目录一并删除
怎么说呢?如果是一个空目录,就删除。如果它的上一级还是空目录,也要删除!依次类推!
在os模块中,有一个os.removedirs()方法,可以实现这个功能!
若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推。
举例:
import os os.removedirs('a')
4. 遍历目录,使用栈
这里的遍历目录,可不是只有一层。有多少层呢?我也不知道!只要目录下面有,就遍历!
到了这里,你可能会想到递归。但是递归这个东西,不是一般人能够理解的。所以我使用栈,这个比较好理解!
在之前的文章中,已经用栈实现了,统计目录占用多少空间。需要将每一个文件大小进行累加计算,请参考链接:
https://www.cnblogs.com/xiao987334176/p/8954715.html
还有一个小的知识点,就是日志模块,也就是logging模块,请参考链接:
https://www.cnblogs.com/xiao987334176/p/8920181.html#autoid-0-2-0
三、正式脚本
这个脚本,是参考了上面链接中的 使用栈统计目录大小。
在这个基础上做了一些小修改,完整代码如下:
#!/usr/bin/env python3 # coding: utf-8 import os import time import datetime import logging class DeleteFile(object): def __init__(self,path): self.path = path def logger(self): """ 写入日志 :return: logger对象 """ logger = logging.getLogger() # 实例化了一个logger对象 # 在国外叫handler,在中国翻译过来,叫句柄 # 设置文件名和编码 fh = logging.FileHandler('delete.log', encoding='utf-8') # 实例化了一个文件句柄 # 格式和文件句柄或者屏幕句柄关联 sh = logging.StreamHandler() # 用于输出到控制台 fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 格式化 fh.setFormatter(fmt) # 格式和文件句柄或者屏幕句柄关联 sh.setFormatter(fmt) # 吸星大法 logger.addHandler(fh) # 吸收写文件功能 和logger关联的只有句柄 logger.addHandler(sh) # 吸收输出屏幕功能 logger.setLevel(logging.DEBUG) # 设置警告级别为debug,此处DEBUG源码为DEBUG = 10 # logger.debug('debug message') # logger.info('info message') # logger.warning('warning message') return logger def delete(self): """ 删除文件 :param path: 文件路径 :return: bool """ file_list = [self.path] # 文件夹列表 # 获取当前时间 today = datetime.datetime.now() # 计算偏移量,前3天 offset = datetime.timedelta(days=-3) # 获取想要的日期的时间,即前3天时间 re_date = (today + offset) # 前3天时间转换为时间戳 re_date_unix = time.mktime(re_date.timetuple()) try: while file_list: # 判断列表是否为空 path = file_list.pop() # 删除列表最后一个元素,并返回给path l = ['E:python_scriptday26'] for item in os.listdir(path): # 遍历列表,path = 'E:python_scriptday26' path2 = os.path.join(path, item) # 组合绝对路径 path2 = 'E:python_scriptday26 est' if os.path.isfile(path2): # 判断绝对路径是否为文件 # 比较时间戳,文件修改时间小于等于3天前 if os.path.getmtime(path2) <= re_date_unix: os.remove(path2) self.logger().debug('删除文件{}'.format(path2)) # 写入日志 else: if not os.listdir(path2): # 判断目录是否为空 # 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.removedirs(path2) self.logger().debug('删除空目录{}'.format(path2)) # 写入日志 else: # 为文件夹时,添加到列表中。再次循环。l = ['E:python_scriptday26 est'] file_list.append(path2) return True except Exception as e: print(e) return False ret = DeleteFile('./').delete() # 当前目录 print(ret)
执行输出:
2018-11-20 11:44:43,254 - root - DEBUG - 删除文件./delpods.sh 2018-11-20 13:53:14,403 - root - DEBUG - 删除空目录./新建文件夹 2018-11-20 13:53:43,406 - root - DEBUG - 删除空目录./ac
与此同时,delete.log日志文件也会记录,和输出是一样的!