• 【Python】Python 将一个文件夹备份到一个 ZIP 文件


    Python 将一个文件夹备份到一个 ZIP 文件

    一、 背景介绍

    假定你正在做一个项目,它的文件保存在C::raw-latex:\AlsPythonBook文件夹中。 你担心工作会丢失,所以希望为整个文件夹创建一个ZIP文件,作为“快照”。 你希望保存不同的版本,希望 ZIP文件的文件名每次创建时都有所变化。 例如 AlsPythonBook_1.zip、AlsPythonBook_2.zip 、 AlsPythonBook_3.zip,等等。你可以手工完成,但这有点烦人, 而且可能不小心弄错 ZIP 文件的编号。 运行一个程序来完成这个烦人的任务会简单得多。

    针对这个项目,打开一个新的文件编辑器窗口, 将它保存为 backupToZip.py 。

    二、操作步骤

    1. 第1步:弄清楚 ZIP 文件的名称

    这个程序的代码将放在一个名为 backupToZip() 的 函数中。这样就更容易将该函数复制粘贴到其他需要 这个功能的Python程序中。在这个程序的末尾,会调用这个 函数进行备份。让你的程序看起来像这样:

    #! python3
    #backupToZip.py - Copies an entire folder and its contents into
    #a ZIP file whose filename increments.

    import zipfile, os

    def backupToZip(folder):
    # Backup the entire contents of “folder” into a ZIP file.

    folder = os.path.abspath(folder) # make sure folder is absolute
    
    # Figure out the filename this code should use based on
    # what files already exist.
    number = 1
    while True:
        zipFilename = os.path.basename(folder) + '_' + str(number) + '.zip'
        if not os.path.exists(zipFilename):
            break
        number = number + 1
    
    # TODO: Create the ZIP file.
    
    # TODO: Walk the entire folder tree and compress the files in each folder.
    print('Done.')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    backupToZip(‘F:\delicious’)
    先完成基本任务:添加 #! 行,描述该程序做什么, 并导入 zipfile 和 os 模块。

    定义 backupToZip() 函数,它只接收一个参数, 即 folder 。这个参数是一个字符串路径, 指向需要备份的文件夹。该函数将决定它创建的 ZIP文件使用什么文件名,然后创建该文件, 遍历 folder 文件夹,将每个子文件夹和文件添加到ZIP文件中。 在源代码中为这些步骤写下 TODO 注释,提醒你稍后来完成。

    第一部分命名这个ZIP文件,使用folder 的绝对路径的基本名称。 如果要备份的文件夹是 C::raw-latex:delicious , ZIP 文件的名称就应该 是 delicious_N.zip ,第一次运行该程 序时 N = l,第二次运行时 N =2,以此类推。

    通过检查 delicious_1.zip 是否存在, 然后检查 delicious_2.zip 是否存在,继续下 去,可以确定 N 应该是什么。用一个名为 number 的变量表示 N, 在一个循环内不断增加它,并调用 os.path.exists() 来 检查该文件是否存在。第一个不存在的文件名将导致循环 break,因此它就发现了新 ZIP 文件的文件名。

    2. 第2步:创建新 ZIP 文件

    接下来让我们创建 ZIP 文件。让你的程序看起来像这样:

    #! python3
    #backupToZip.py - Copies an entire folder and its contents into
    #a ZIP file whose filename increments.

    –snip–
    while True:
    zipFilename = os.path.basename(folder) + ‘_’ + str(number) + ‘.zip’
    if not os.path.exists(zipFilename):
    break
    number = number + 1

    # Create the ZIP file.
    print('Creating %s...' % (zipFilename))
    backupZip = zipfile.ZipFile(zipFilename, 'w')
    
    # TODO: Walk the entire folder tree and compress the files in each folder.
    print('Done.')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    backupToZip(‘F:\delicious’)
    既然新 ZIP 文件的文件名保存在 zipFilename 变量中, 你就可以调用 zipfile.ZipFile() , 实际创建这个 ZIP 文件 。确保传入 ‘w’ 作为 第二个参数,这样 ZIP 文件以写模式打开。

    3. 第3步:遍历目录树并添加到 ZIP 文件

    现在需要使用 os.walk() 函数, 列出文件夹以及子文件夹中的每个文件。 让你的程序看起来像这样:

    #! python3

    backupToZip.py

    Copies an entire folder and its contents into

    a zip file whose filename increments.

    import zipfile, os

    folder = os.path.abspath(‘.’) # make sure folder is absolute
    注意, 不要将备份的结果文件放到要备份的文件夹中,不然备份程序会循环读取备份的结果文件,导致结果文件无限变大,直至充满硬盘空间。

    这里为了方便将文件保存到 /tmp 文件夹中。实际使用要放到恰当的位置。

    Figure out the filename this code should used based on

    what files already exist.

    number = 1
    while True:
    zipFilename = ‘/tmp/xx_’ + os.path.basename(folder) + ‘_’ + str(number) + ‘.zip’
    if not os.path.exists(zipFilename):
    break
    number = number + 1

    Create the zip file.

    print(‘Creating %s…’ % (zipFilename))
    backupZip = zipfile.ZipFile(zipFilename, ‘w’)

    Walk the entire folder tree and compress the files in each folder.

    for foldername, subfolders, filenames in os.walk(folder):
    print(‘Adding files in %s…’ % (foldername))
    # Add the current folder to the ZIP file.
    backupZip.write(foldername)

    # Add all the files in this folder to the ZIP file.
    for filename in filenames:
        if filename.startswith(os.path.basename(folder) + '_') and filename.endswith('.zip'):
            continue # don't backup the backup ZIP files
        backupZip.write(os.path.join(foldername, filename))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    backupZip.close()
    print(‘Done.’)
    Creating /tmp/xx_ch03_file_1.zip…
    Adding files in /home/bk/book-jubook/python/jubook_python/pt04_essential/ch03_file…
    Adding files in /home/bk/book-jubook/python/jubook_python/pt04_essential/ch03_file/.ipynb_checkpoints…
    Done.
    可以在 for 循环中使用 os.walk ,在每次迭代中, 它将返回这次迭代当前的文件夹名称、这个文件夹中的子文件夹, 以及这个文件夹中的文件名。

    在这个 for 循环中,该文件夹被添加到 ZIP 文件。 嵌套的 for 循环将遍历 filenames 列表中的每个文件。 每个文件都被添加到 ZIP 文件中,以前生成的备份 ZIP 文件除外。

    如果运行该程序,它产生的输出看起来像这样:

    Creating delicious_1.zip…
    Adding files in C:\delicious…
    Adding files in C:\delicious\cats…
    Adding files in C:\delicious\waffles…
    Adding files in C:\delicious\walnut…
    Adding files in C:\delicious\walnut\waffles…
    Done.
    第二次运行它时,它将 C::raw-latex:delidous 中的所有文件放进一个 ZIP 文件, 命名为 delicious_2.zip,以此类推。

    4. 第4步:类似程序的想法

    你可以在其他程序中遍历一个目录树, 将文件添加到压缩的 ZIP 归档文件中。 例如,你可以编程做下面的事情:

    遍历一个目录树,将特定扩展名的文件归档,诸如 .txt 或 .py ,并排除其他文件。

    遍历一个目录树,将除 .txt 和 .py 文件以外的其他文件归档。

    在一个目录树中查找文件夹,它包含的文件数最多,或者使用的磁盘空间最大。

    5. 小结

    即使你是一个有经验的计算机用户, 可能也会用鼠标和键盘手工处理文件。 现在的文件浏览器使得处理少量文件的工作很容易。 但有时候,如果用计算机的浏览器, 你需要完成的任务可能要花几个小时。

    os 和 shutil 模块提供了一些函数, 用于复制、移动、改名和删除文件。在删除文件时, 你可能希望使用 send2trash 模块, 将文件移动到回收站或垃圾箱, 而不是永久地删除它们。在编程处理文件时, 最好是先注释掉实际会复制/移动/改名/删除 文件的代码,添加 print() 调用, 这样你就可以运行该程序,验证它实际会做什么。

    通常,你不仅需要对一个文件夹中的文件执行这些操作, 而是对所有下级子文件夹执行操作。os.walk() 函数 将处理这个艰苦工作,遍历文件夹,这样你就可以专注 于程序需要对其中的文件做什么。

    zipfile 模块提供了一种方法,用Python压缩和解压ZIP 归档文件。和 os 和 shutil 模块中的文件处理函数 一起使用,很容易将硬盘上任意位置的一些文件打包。 和许多独立的文件相比,这些 ZIP 文件更容易上传到网站, 或作为 E-mail 附件发送。

    本书前面几章提供了源代码让你拷贝。 但如果你编写自己的程序,可能在第一次编写时不会完美无缺。 下一章将聚焦于一些Python模块,它们帮助你分析和调试程序, 这样就能让程序很快正确运行。

    6.重点疑问

    1.shutil.copy() 和shutil.copytree() 之间的区别是什么?

    2.什么函数用于文件改名?

    3.send2trash 和 shutil 模块中的删除函数之间的区别是什么?

    4.ZipFile 对象有一个 close() 方法,就像 File 对象的 close() 方法。 ZipFile 对象 的什么方法等价于 File 对象的 open() 方法?

  • 相关阅读:
    Python语言基础与应用-北京大学-陈斌-P29-28-计算和控制流:控制流:上机:基本计算程序-给定一个英文数字字符串,打印相应阿拉伯数字字符串-上机代码
    spring cache (默认方式)
    [2022CISCN]初赛 复现
    【App自动化测试】(八)三种等待方式——强制等待、隐式等待、显示等待
    离散数学 ---- 图论基础 --- 图的引入,表示与分类
    【Vuforia+Unity】AR04-地面、桌面平面识别功能(Ground Plane Target)
    《异 步》
    算法必刷系列之查找、排序
    一文搞定垃圾回收器
    FANUC机器人零点复归的报警原因分析和零点标定相关步骤
  • 原文地址:https://blog.csdn.net/wjianwei666/article/details/133385815