需求
1.可以对目录以及目录下的子文件进行备份,并针对修改时间进行备份,若本文件的修改时间与本来就存在的修改时间相同,则不备份(精确到秒即可)
2.需要记录日志,尤其对重复文件的复制,其他程序可根据日志的格式进行解析并监控(后续再写监控程序,备份发生意外短信通知【短信通知需要有API提供接口才行】)
3.程序自动启动
分析【设计】
- WBS
1.1. 日志打印需要保存,考虑到应用本身的应用,本程序输出的日志仅保留7天
1.2. 文件需要遍历至子文件与子文件夹 需要用到递归算法
1.3. 获取文件修改时间进行对比
1.4. 编写windows【任务计划程序】或Linux的【crontab】程序(自动化需求)程序自动启动时需要让自动登录的用户拥有启动程序的权限,windows的程序是根据谁设置的程序来处理,linux只要将脚本设置777权限就可以了(其实只要运行权限就行。。。r权限,懒人解决办法777)
自动化方式
代码
import os
import shutil
import time
import logging
from logging.handlers import TimedRotatingFileHandler
# 要备份的路径
A = "C:\\Users\\ligen\\Documents\\StarCraft II\\\Accounts\\"
# 备份到哪里的路径
B = "I:\\SCⅡbackup\\StarCraft II\\\Accounts"
'''
上面这段配置可以通过程序读取key-value 键值对用于多功能备份
'''
log = logging.getLogger()
log.setLevel(logging.DEBUG)
'''
日志初始化
'''
logFilePath = 'E:\\LOGS\\BackSCIIFileLOGS\\BackSCIIFileLog.log'
'''
log 日志路径,养成打印日志的习惯是对程序开发有很多好处
'''
# 日志模块
log_fmt = '%(asctime)s\tFile \"%(filename)s\",line %(lineno)s\t%(levelname)s: %(message)s'
formatter = logging.Formatter(log_fmt)
'''
日志打印格式
'''
log_file_handler = TimedRotatingFileHandler(filename=logFilePath, when="D", interval=1, backupCount=7)
log_file_handler.setFormatter(formatter)
log_file_handler.setLevel(logging.DEBUG)
'''
日志打印方式 日切,最多保留7天
'''
log.addHandler(log_file_handler)
# 校验规则 判断B内的文件与A 不同
def backupcheck(file_path):
"""
校验规则 获取文件修改时间 两个文件的修改时间一致则继续,注意本方法返回的是时间而不是是否
:param file_path: 文件路径
:return: 文件修改时间 yyyy-mm-dd HH-MM-SS 格式
"""
full_path = os.path.join(file_path)
mtime = os.stat(full_path).st_mtime
file_modify_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(mtime))
log.debug("检查重复文件:" + full_path + "--" + file_modify_time)
return file_modify_time
def main(path, out):
"""
:param path: 要被复制的路径
:param out: 要被输出到的路径
:return: 没有返回值
"""
log.debug("处理文件/目录 [ Process directories and files ]:[ " + path + " ]--[ " + out + " ]")
for files in os.listdir(path):
'''路径下的文件'''
name = os.path.join(path, files)
back_name = os.path.join(out, files)
if os.path.isfile(name):
if os.path.isfile(back_name):
if backupcheck(name) != backupcheck(back_name):
log.debug("复制重复文件 [ Copy duplicate file ]:[ " + name + " ]--[ " + back_name + " ]")
shutil.copy(name, back_name)
else:
log.debug("复制新文件 [ Copy new file ]:[ " + name + " ]--[ " + back_name + " ]")
shutil.copy(name, back_name)
else:
if not os.path.isdir(back_name):
os.makedirs(back_name)
'''
递归算法
'''
main(name, back_name)
if __name__ == '__main__':
log.debug("-------------------------- 开始处理备份任务 -- [ start ] --------------------------")
m = os.path.isfile(A)
n = os.path.isfile(B)
if m == 1:
log.error("A:[ " + A + " ]不是目录")
exit(1)
if n == 1:
log.error("B:[ " + B + " ]不是目录")
log.error("-------------------------- 结束处理备份任务 -- [ end ] --------------------------")
exit(1)
main(A, B)
log.debug("-------------------------- 结束处理备份任务 -- [ end ] --------------------------")
质量检查
打印日志的语句是修改过的,也仅仅是输出变了,大家请不要介意
2019-12-30 21:09:52,431 File "BackSCIIFile.py",line 76 DEBUG: ----------------------------------------开始处理备份任务----------------------------------------
2019-12-30 21:09:52,431 File "BackSCIIFile.py",line 57 DEBUG: 处理文件/目录:C:\Users\ligen\Documents\StarCraft II\Accounts\1.txt--I:\SCⅡbackup\StarCraft II\Accounts
2019-12-30 21:19:23,972 File "BackSCIIFile.py",line 76 DEBUG: ----------------------------------------开始处理备份任务----------------------------------------
2019-12-30 21:19:23,972 File "BackSCIIFile.py",line 80 ERROR: A:[C:\Users\ligen\Documents\StarCraft II\Accounts\1.txt]不是目录
2019-12-30 21:19:23,972 File "BackSCIIFile.py",line 80 DEBUG: ----------------------------------------结束处理备份任务----------------------------------------
2019-12-30 21:26:04,625 File "BackSCIIFile.py",line 80 DEBUG: ----------------------------------------开始处理备份任务----------------------------------------
2019-12-30 21:26:04,625 File "BackSCIIFile.py",line 57 DEBUG: 处理文件/目录:C:\Users\ligen\Documents\StarCraft II\Accounts--I:\SCⅡbackup\StarCraft II\Accounts
2019-12-30 21:26:04,626 File "BackSCIIFile.py",line 68 DEBUG: 复制新文件:C:\Users\ligen\Documents\StarCraft II\Accounts\1.txt--I:\SCⅡbackup\StarCraft II\Accounts\1.txt
...........
2019-12-30 21:26:04,937 File "BackSCIIFile.py",line 65 DEBUG: 复制重复文件:C:\Users\ligen\Documents\StarCraft II\Accounts\197639373\Variables.txt--I:\SCⅡbackup\StarCraft II\Accounts\197639373\Variables.txt
2019-12-30 21:26:04,939 File "BackSCIIFile.py",line 90 DEBUG: ----------------------------------------结束处理备份任务----------------------------------------