Python世界:文件自动化备份实践

Python世界:文件自动化备份实践

背景任务


问题来自《简明Python教程》中的解决问题一章,提出实现:对指定目录做定期自动化备份。

最重要的改进方向是不使用 os.system 方法来创建归档文件, 而是使用 zipfile 或 tarfile 内置的模块来创建它们的归档文件。 ------《简明Python教程》

本文在其第4版示范代码基础上,尝试采用内部python自带库zipfile的方式,实现功能:进行文件压缩备份。

实现思路


文件命名demo_backup_v5.py,视为改进的第5版实现,除采用自带zipfile的方式,还有以下更新:

  • 支持外部自定义设参
  • 支持自定义压缩文件内目录名称,并去除冗余绝对路径

编码思路:

  1. 指定待备份目录和目标备份路径
  2. 按日期建立文件夹
  3. 按时间建立压缩文件

首先,进行输入前处理,对目录路径进行处理:

python 复制代码
    if len(sys.argv) >= 3: # 有外部入参,取外部输入
        tobe_backup_dir = sys.argv[1] # input dir, sys.argv[0] the name of python file
        target_dir = sys.argv[2] # output dir
        comment_info = input("enter a comment information => ")
    else: # 无外部入参,则内部设定
        # tobe_backup_dir = "C:\\Users\\other"
        tobe_backup_dir = r"E:\roma_data\code_data_in\inbox"
        target_dir = "E:\\roma_data\\code_test"
        comment_info = "test demo"

其次,正式进入程序处理函数:backup_proc(),先判断目标备份目录是否存在,如不存在,先构造1个。

接着,按日期today进行备份文件夹创建,按时间now进行压缩文件命名备份。

最后,遍历待备份源目录所有文件,将其压缩为时间now命名的zip文件中。

python 复制代码
# 仅支持单个目录备份
def backup_proc(tobe_backup_dir, target_dir, comment_info):
    if_not_exist_then_mkdir(target_dir)
    today = target_dir + os.sep + "backup_" + time.strftime("%Y%m%d") # 年、月、日
    now = time.strftime("%H%M%S") # 小时、分钟、秒
    print("Successfully created")

    # zip命名及目录处理
    prefix = today + os.sep + now
    if len(comment_info) == 0:
        target = prefix + '.zip'
    else:
        target = prefix + "_" + comment_info.replace(" ", "_") + '.zip'
    if_not_exist_then_mkdir(today)

    # 参考链接:https://blog.csdn.net/csrh131/article/details/107895772
    # zipfile打开文件句柄, with打开不用手动关闭
    with zipfile.ZipFile(target, "w", zipfile.ZIP_DEFLATED) as f:
        for root_dir, dir_list, file_list in os.walk(tobe_backup_dir): # 能遍历子目录所有文件
            for name in file_list:
                target_file = os.path.join(root_dir, name)
                all_file_direct_zip = False
                if all_file_direct_zip: # 不加内部目录
                    zip_internal_dir_prefix = os.sep
                else: # 加内部目录
                    zip_internal_dir_prefix = comment_info + os.sep
                # 去掉绝对路径指定压缩包里面的文件所在目录结构   
                arcname = zip_internal_dir_prefix + target_file.replace(tobe_backup_dir, "")
                # arcname = target_file.replace(tobe_backup_dir, "")
                f.write(target_file, arcname=arcname)
    return

测试用例

  • python外部入参
    • python demo_backup_v5.py "E:\roma_data\code_data_in\inbox" "E:\roma_data\code_test"
  • python内部入参
    • python demo_backup_v5.py

本实现的一个缺点是,仅支持单一目录备份,秉持短小精悍原则,如需多目录备份可在以上做加法。

坑点小结


坑点1:不要多级目录,去除绝对路径

解决:zipfile压缩包如何避免绝对路径

坑点2:Unable to find python module

运行if not os.path.exists(path_in)报错。

根因:python有多个版本,3.6运行时不支持,需要>=3.8。

解决:Ctrl + Shift + P,输入Select Interpreter,指定高版本版本解释器。

参考:link1link2

坑点3:TypeError: stat: path should be string, bytes, os.PathLike or integer, not list

根因:输入的path路径是个list没有拆解开,索引访问元素给string输入。

示例实现:

python 复制代码
# -*- coding: utf-8 -*-
"""
Created on 09/03/24
功能:文件备份
1、指定待备份目录和目标备份路径
2、按日期建立文件夹
3、按时间建立压缩文件
"""

import os
import time
import sys
import zipfile


# 判断该目录是否存在,如不存在,则创建
def if_not_exist_then_mkdir(path_in):
    if not os.path.exists(path_in):
        os.mkdir(path_in)
        print("Successfully created directory", path_in)


# 仅支持单个目录备份
def backup_proc(tobe_backup_dir, target_dir, comment_info):
    if_not_exist_then_mkdir(target_dir)
    today = target_dir + os.sep + "backup_" + time.strftime("%Y%m%d") # 年、月、日
    now = time.strftime("%H%M%S") # 小时、分钟、秒
    print("Successfully created")

    # zip命名及目录处理
    prefix = today + os.sep + now
    if len(comment_info) == 0:
        target = prefix + '.zip'
    else:
        target = prefix + "_" + comment_info.replace(" ", "_") + '.zip'
    if_not_exist_then_mkdir(today)

    # 参考链接:https://blog.csdn.net/csrh131/article/details/107895772
    # zipfile打开文件句柄, with打开不用手动关闭
    with zipfile.ZipFile(target, "w", zipfile.ZIP_DEFLATED) as f:
        for root_dir, dir_list, file_list in os.walk(tobe_backup_dir): # 能遍历子目录所有文件
            for name in file_list:
                target_file = os.path.join(root_dir, name)
                all_file_direct_zip = False
                if all_file_direct_zip: # 不加内部目录
                    zip_internal_dir_prefix = os.sep
                else: # 加内部目录
                    zip_internal_dir_prefix = comment_info + os.sep
                # 去掉绝对路径指定压缩包里面的文件所在目录结构   
                arcname = zip_internal_dir_prefix + target_file.replace(tobe_backup_dir, "")
                # arcname = target_file.replace(tobe_backup_dir, "")
                f.write(target_file, arcname=arcname)
    return


if __name__ == '__main__':
    print('start!')

    # 前处理
    if len(sys.argv) >= 3: # 有外部入参,取外部输入
        tobe_backup_dir = sys.argv[1] # input dir, sys.argv[0] the name of python file
        target_dir = sys.argv[2] # output dir
        comment_info = input("enter a comment information => ")
    else: # 无外部入参,则内部设定
        # tobe_backup_dir = "C:\\Users\\other"
        tobe_backup_dir = r"E:\roma_data\code_data_in\inbox"
        target_dir = "E:\\roma_data\\code_test"
        comment_info = "test demo"

    # 正式运行
    backup_proc(tobe_backup_dir, target_dir, comment_info)

    # 正式退出main函数进程,以免main函数空跑
    print('done!')
    sys.exit()
相关推荐
聆风吟º7 小时前
CANN开源项目深度实践:基于amct-toolkit实现自动化模型量化与精度保障策略
运维·开源·自动化·cann
Java后端的Ai之路7 小时前
【Python 教程15】-Python和Web
python
Coder个人博客7 小时前
Linux6.19-ARM64 mm mmu子模块深入分析
大数据·linux·车载系统·系统架构·系统安全·鸿蒙系统
冬奇Lab8 小时前
一天一个开源项目(第15篇):MapToPoster - 用代码将城市地图转换为精美的海报设计
python·开源
Doro再努力10 小时前
Vim 快速上手实操手册:从入门到生产环境实战
linux·编辑器·vim
wypywyp10 小时前
8. ubuntu 虚拟机 linux 服务器 TCP/IP 概念辨析
linux·服务器·ubuntu
二十雨辰10 小时前
[python]-AI大模型
开发语言·人工智能·python
Doro再努力10 小时前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim
senijusene10 小时前
Linux软件编程:IO编程,标准IO(1)
linux·运维·服务器
Yvonne爱编码11 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python