当前位置: 首页 > news >正文

Python3 中使用zipfile进行文件(夹)的压缩、解压缩

一、文件压缩与解压缩模块 zipfile简介

zipfile 是 Python 标准库中用于处理 ZIP 压缩文件的模块,提供了创建、读取、写入、解压 ZIP 文件的完整功能。它支持多种压缩算法,无需安装额外依赖,是处理 ZIP 格式的首选工具。

核心功能与常用类

  1. zipfile.ZipFile
    这是模块的核心类,用于创建和操作 ZIP 文件,常用参数:
    • file:ZIP 文件路径或文件对象
    • mode:操作模式('r' 读取、'w' 创建、'a' 追加)
    • compression:压缩算法(ZIP_STORED 无压缩,ZIP_DEFLATED 常用压缩)

常用操作示例

1. 读取 ZIP 文件内容
import zipfilewith zipfile.ZipFile('example.zip', 'r') as zf:# 查看压缩包内所有文件print(zf.namelist())  # 返回文件名列表# 查看文件信息(大小、压缩率等)for info in zf.infolist():print(f"文件名: {info.filename}, 原始大小: {info.file_size}, 压缩后: {info.compress_size}")
2. 解压 ZIP 文件
import zipfilewith zipfile.ZipFile('example.zip', 'r') as zf:# 解压所有文件到指定目录(默认当前目录)zf.extractall(path='解压目录')# 解压单个文件zf.extract('文件路径/文件名.txt', path='单个文件解压目录')
3. 创建 ZIP 文件(压缩文件/文件夹)
import zipfile
import os# 压缩单个文件
with zipfile.ZipFile('output.zip', 'w', zipfile.ZIP_DEFLATED) as zf:zf.write('file1.txt', arcname='file1.txt')  # arcname 可指定压缩包内文件名# 压缩文件夹(含子目录)
def zip_folder(folder_path, zip_path):with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:for root, dirs, files in os.walk(folder_path):for file in files:file_path = os.path.join(root, file)# 保持相对路径,确保文件夹结构arcname = os.path.relpath(file_path, os.path.dirname(folder_path))zf.write(file_path, arcname=arcname)zip_folder('需要压缩的文件夹', 'result.zip')
4. 向现有 ZIP 追加文件
import zipfilewith zipfile.ZipFile('existing.zip', 'a', zipfile.ZIP_DEFLATED) as zf:zf.write('new_file.txt')  # 追加新文件到已有压缩包

注意事项

  • 压缩算法ZIP_DEFLATED 需要系统支持 zlib 库(通常默认支持),否则需使用无压缩的 ZIP_STORED
  • 路径处理:压缩文件夹时需通过 arcname 控制路径,避免生成冗余的绝对路径。
  • 大型文件:处理大文件时建议使用 with 语句,确保资源正确释放。

通过 zipfile 模块,可轻松实现 ZIP 文件的全流程管理,满足日常压缩/解压需求。

二、案例实操

2.0 测试文件准备

原始结构为:

dir_level_1/
├── file1.txt
├── subfolder1/
│   └── file2.txt
└── subfolder2/└── subsubfolder/└── file3.txt

程序设计初衷:

将目录“dir_level_1”下所有的文件、子文件夹、子文件夹下的文件,安装原先的层次结构,压缩为一个文件“dir_level_1.zip”。

2.1 综合案例:实现文件压缩、查看压缩内容、解压

"""14-5 文件压缩与解压模块-zipFile操作系统提供将一般文件或目录进行压缩的功能,压缩后的扩展名是zip,Python有 zipFile 模块也可以将文件或目录压缩以及解压缩。压缩文件或目录:zipfile.ZipFile(file_name, mode='w', compression=ZIP_DEFLATED)file_name: 压缩文件的名称mode: 压缩文件的模式,w表示写入,a表示追加compression: 压缩算法,ZIP_DEFLATED表示使用 deflate 算法进行压缩解压文件或目录:zipfile.ZipFile(file_name, mode='r')14-5-1 执行文件或目录的压缩说明:执行文件压缩前首先要使用ZipFile()方法创建一个压缩后的文件对象,在这个方法中另外要加上“w”参数,表明未来是提供 write() 方法写入文件。语法:fileZip = zipfile.ZipFile('out.zip', mode='w',compression=ZIP_DEFLATED)上述fileZip和out.zip皆可以自由命名,fileZip是压缩文件对象,代表的out.zip,未来将被压缩的文件数据写入到此对象中,就可以将结果保存为 out.zip 文件了。注意:1、虽然ZipFile()无法执行整个目录的压缩,不过可以使用循环(递归)方式将目录底下的文件或文件夹进行压缩,即可达到压缩整个目录的目的。详见:c14-5.2_zip_with_hierarchy.py14-5-2 读取zip文件说明:1、listZipInfo.namelist() : 返回zip文件中所有文件的名称列表(List)。2、listZipInfo.infolist() : 返回各个元素的属性,如文件名、文件大小、压缩结果大小、文件时间、文件CRC码等。语法:listZipInfo = zipfile.ZipFile('dir_level_1.zip', 'r')print(listZipInfo.namelist()) # 获取文件(夹)列表print('\n')for fileInfo in listZipInfo.infolist():print(fileInfo.filename,'\t', fileInfo.file_size,'\t', fileInfo.compress_size)14-5-3 解压缩zip文件说明:1、zipfile.extractall() : 解压缩zip文件。2、zipfile.extract(fileName) : 解压缩指定文件。3、zipfile.extractall(path) : 解压缩zip文件到指定目录。语法:listZipInfo = zipfile.ZipFile('dir_level_1.zip', 'r')listZipInfo.extractall() # 解压所有文件listZipInfo.extract('dir_level_1.zip') # 解压指定文件listZipInfo.close()"""print("----------------------- 案例-14-5-1 执行文件或目录的压缩 -----------------------")
# ch14_41.py : 将当前工作目录下的 dir_level_1 目录压缩,压缩结果存储在 dir_level_1.zip 文件中.
"""
代码说明:这行代码的作用是遍历dir_level_1目录下的所有文件和目录(但不包括子目录中的内容)。具体解释如下:glob.glob('dir_level_1/*'):glob是一个用于匹配文件路径的模块,支持Unix shell-style的通配符
dir_level_1/*表示匹配dir_level_1目录下的所有文件和目录(一级内容)
这个表达式会返回一个包含所有匹配路径的列表
for name in ...:遍历glob返回的每个文件/目录路径
根据对项目文件结构的查看,dir_level_1目录包含以下内容:- 多个文件:2.docx、out14_27.txt等- 一个子目录:dir_level_2(包含1.docx和1.txt)需要注意的是,dir_level_1/*这种模式只会匹配dir_level_1目录下的直接内容,不会递归匹配子目录中的文件。所以在示例中,它会匹配到2.docx、out14_27.txt等文件以及 dir_level_2目录本身,但不会匹配dir_level_2 目录中的1.docx和1.txt。在代码中,这些匹配到的文件和目录会被逐一添加到dir_level_1.zip压缩文件中。
"""
import zipfile
import glob, osfileZip = zipfile.ZipFile('dir_level_1.zip', 'w')
for name in glob.glob('dir_level_1/*'):            # 遍历指定目录下的所有文件,但测试下来,仅会压缩dir_level_1下首层文件及文件夹,而不会将二层dir_level_1\dir_level_2下的文件(如1.txt,1.docx)压缩进dir_level_1.zip中fileZip.write(name, os.path.basename(name), zipfile.ZIP_DEFLATED) # 参数3为压缩方式fileZip.close()print("----------------------- 案例-14-5-2 读取zip文件 -----------------------")
# ch14_41.py : 
import zipfilelistZipInfo = zipfile.ZipFile('dir_level_1.zip', 'r')
print(listZipInfo.namelist()) # 获取文件(夹)列表
print('\n')
for fileInfo in listZipInfo.infolist():print(fileInfo.filename,'\t', fileInfo.file_size,'\t', fileInfo.compress_size, '\t', fileInfo.date_time, '\t', fileInfo.CRC)
'''
['2.docx', 'out14_27.txt', 'out14_28.txt', 'out14_29.txt', 'out14_30.txt', 'out14_31.txt', 'out41_V3.zip', 'dir_level_2/']2.docx           10240   9080    (2025, 8, 3, 1, 4, 52)          1145032402
out14_27.txt     13      15      (2025, 8, 2, 18, 23, 8)         2445962250
out14_28.txt     3       5       (2025, 8, 2, 18, 23, 8)         595022058
out14_29.txt     47      34      (2025, 8, 2, 18, 23, 8)         1873662565
out14_30.txt     51      36      (2025, 8, 2, 18, 23, 8)         24013343
out14_31.txt     101     42      (2025, 8, 2, 18, 23, 8)         676495025
out41_V3.zip     97041   71141   (2025, 8, 3, 9, 40, 58)         2754552733
dir_level_2/     0       0       (2025, 8, 3, 0, 59, 16)         0
'''print("----------------------- 案例-14-5-3 解压缩zip文件 -----------------------")
# ch14_43.py : 将程序实例 ch14_41.py 所建立的 dir_level_1.zip 解压缩,同时将解压结果存入 out43 目录
import zipfilefileUnZip = zipfile.ZipFile("dir_level_1.zip", "r")
fileUnZip.extractall("out43")
fileUnZip.close()

2.2 压缩方法优化-V1版本

上一版压缩方法的缺陷

代码中:

fileZip = zipfile.ZipFile('dir_level_1.zip', 'w')
for name in glob.glob('dir_level_1/*'):           fileZip.write(name, os.path.basename(name), zipfile.ZIP_DEFLATED)

这里的fileZip对象无法将文件夹下dir_level_1下文件夹dir_level_2中的文件1.docx压缩进来,而只会将dir_level_2文件夹本身压缩进来,未达到程序实现功能的初衷。

改进说明

要解决级联压缩文件夹(包含子文件夹结构)的问题,需要递归遍历文件夹中的所有文件,并保持原有的目录结构。

代码解释

要解决级联压缩文件夹(包含子文件夹结构)的问题,需要递归遍历文件夹中的所有文件,并保持原有的目录结构。以下是实现这一功能的完整代码:

代码清单

zip_recursive.py

import zipfile
import osdef zip_directory(folder_path, zip_file):"""递归压缩文件夹及其子目录中的所有文件参数:folder_path (str): 要压缩的文件夹路径zip_file (zipfile.ZipFile): 已打开的ZipFile对象"""# 遍历文件夹中的所有内容for item in os.listdir(folder_path):item_path = os.path.join(folder_path, item)# 如果是文件,直接添加到压缩包if os.path.isfile(item_path):# 计算相对路径,保持目录结构arcname = os.path.relpath(item_path, os.path.dirname(folder_path))zip_file.write(item_path, arcname=arcname)print(f"已添加文件: {arcname}")# 如果是文件夹,递归处理elif os.path.isdir(item_path):zip_directory(item_path, zip_file)# 使用示例
if __name__ == "__main__":# 要压缩的根文件夹路径root_folder = "dir_level_1"# 压缩文件保存路径zip_path = "dir_level_1.zip"# 创建并打开zip文件with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:zip_directory(root_folder, zipf)print(f"压缩完成,文件保存为: {zip_path}")

代码解析:

  1. 核心函数zip_directory 函数通过递归方式处理文件夹及其子文件夹

    • 对于文件:直接添加到压缩包,并通过 arcname 参数保持相对路径
    • 对于子文件夹:递归调用自身处理
  2. 关键技术点

    • 使用 os.path.relpath 计算文件相对路径,确保压缩包内保持原有的目录结构
    • 使用 with 语句管理 ZipFile 对象,确保资源正确释放
    • 使用 ZIP_DEFLATED 模式创建压缩的zip文件(而不是仅存储)
  3. 使用方法

    • root_folder 设置为根文件夹路径(如 “dir_level_1”)
    • 运行程序后,会将 dir_level_1 下所有文件、子目录(包括 dir_level_2 中的 1.docx)完整压缩到 dir_level_1.zip 中

这样处理后,压缩包内会完整保留原有的文件夹层次结构,而不是仅压缩最内层的文件夹。

2.3 压缩方法优化-V2版本

V1版缺陷

这样实现不能忠实的反馈原文件夹结构,本意是希望原先dir_level_1下的文件夹和文件都压缩至dir_level_1目录下,而目前的代码实现的逻辑是dir_level_1下的文件是放在了dir_level_1下,但dir_level_1下的文件夹,如 dir_level_2 却没有放在dir_level_1下,而是与dir_level_1平级了。

改进说明

要解决文件夹结构忠实还原的问题,关键在于正确设置压缩包内的相对路径。以下是改进后的代码,确保所有文件和子文件夹都正确嵌套在根目录下。

  1. 核心改进点

    • 明确将根文件夹名称(root_basename)作为压缩包内的顶级目录
    • 所有文件和子文件夹都通过 os.path.join(root_basename, ...) 构建路径,确保嵌套在根目录下
    • 使用 zip_subdirectory 专门处理子文件夹,保持完整的层级关系
  2. 结构保证
    假设原始结构为:

    dir_level_1/
    ├── file1.txt
    ├── subfolder1/
    │   └── file2.txt
    └── subfolder2/└── subsubfolder/└── file3.txt
    

    压缩后在zip文件中会保持完全相同的结构:

    dir_level_1/
    ├── file1.txt
    ├── subfolder1/
    │   └── file2.txt
    └── subfolder2/└── subsubfolder/└── file3.txt
    
  3. 使用方法

    • root_folder 设置为根目录(如 “dir_level_1”)
    • 运行程序后,所有内容都会被正确压缩到该根目录下,不会出现平级问题

这种实现方式能精确还原原始文件夹的层级结构,确保子文件夹都正确嵌套在指定的根目录下。

代码清单

zip_with_hierarchy.py

import zipfile
import osdef zip_directory(root_folder, zip_file):"""递归压缩指定文件夹,保持完整的目录结构参数:root_folder (str): 要压缩的根文件夹路径zip_file (zipfile.ZipFile): 已打开的ZipFile对象"""# 获取根文件夹的基本名称,作为压缩包内的顶级目录root_basename = os.path.basename(root_folder)# 遍历根文件夹中的所有内容for item in os.listdir(root_folder):item_path = os.path.join(root_folder, item)# 构建压缩包内的相对路径,确保所有内容都在根文件夹名下arcname = os.path.join(root_basename, item)if os.path.isfile(item_path):# 添加文件,使用构建的相对路径zip_file.write(item_path, arcname=arcname)print(f"已添加文件: {arcname}")elif os.path.isdir(item_path):# 递归处理子文件夹,同时保持目录结构zip_subdirectory(item_path, zip_file, root_basename)def zip_subdirectory(subfolder_path, zip_file, root_basename):"""递归处理子文件夹,保持相对路径结构"""# 获取当前子文件夹相对于根文件夹的路径rel_path = os.path.relpath(subfolder_path, os.path.dirname(subfolder_path))# 构建压缩包内的完整路径base_arcname = os.path.join(root_basename, rel_path)for item in os.listdir(subfolder_path):item_path = os.path.join(subfolder_path, item)arcname = os.path.join(base_arcname, item)if os.path.isfile(item_path):zip_file.write(item_path, arcname=arcname)print(f"已添加文件: {arcname}")elif os.path.isdir(item_path):# 递归处理更深层次的子文件夹zip_subdirectory(item_path, zip_file, root_basename)# 使用示例
if __name__ == "__main__":# 要压缩的根文件夹路径root_folder = "dir_level_1"# 压缩文件保存路径zip_path = "dir_level_1.zip"# 确保根文件夹存在if not os.path.isdir(root_folder):print(f"错误: 文件夹 '{root_folder}' 不存在")else:# 创建并打开zip文件,使用DEFLATED模式进行压缩with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:zip_directory(root_folder, zipf)print(f"压缩完成,文件保存为: {zip_path}")
http://www.lryc.cn/news/609081.html

相关文章:

  • Qt-vs加载exe图标
  • 【机器人】VLN-R1 微调 | 增强训练 | 连续导航
  • 江协科技STM32 14-1 WDG看门狗
  • 一键安装RabbitMQ脚本
  • 数据结构(概念及链表)
  • 【数据分享】各省粮食外贸依存度、粮食波动率等粮食相关数据合集(2011-2022)(获取方式看文末)
  • 达梦数据库备份与还原终极指南:从基础到增量策略实战
  • 【2025/08/03】GitHub 今日热门项目
  • Spring 核心之 Bean 管理:配置、作用域与生命周期详解
  • 计算机核心概念辨析与解析
  • LeetCode 2122.还原原数组
  • OpenWrt | 如何在 ucode 脚本中打印日志
  • C语言的基本结构
  • 加密流量论文复现:《Detecting DNS over HTTPS based data exfiltration》(上)
  • 代码随想录算法训练营第五十八天|动态规划part8
  • Linux 内存调优之如何限制进程、系统级别内存资源
  • 论文阅读笔记:《Dataset Condensation with Distribution Matching》
  • 学习方法论
  • React中的Hooks
  • 【深度学习新浪潮】谷歌新推出的AlphaEarth是款什么产品?
  • Unity_数据持久化_XML序列化与反序列化
  • 05.Redis 图形工具RDM
  • 6.1、Redis多级缓存原理和优化、Redis部分参数优化调整
  • Python篇--- Python 的加载、缓存、覆盖机制
  • 01.Redis 概述
  • 复现cacti的RCE
  • ELECTRICAL靶机
  • [硬件电路-145]:模拟电路 - 常见的电源芯片、用途、管脚定义
  • Spring+K8s+AI实战:3全栈开发指南
  • LeetCode Hot 100,快速学习,不断更