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.pswp.cn/news/917526.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/917526.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Java客户端使用Redis

目录 第一步:开放Redis外部连接配置 第二步:配置端口转发 第三步:在IDEA中导入依赖 第四步:编写代码命令 连接环境:Java客户端为本地IDEA,Redis服务器安装在云服务器Ubuntu系统中。 第一步:开…

【MySQL】MySQL索引—B树/B+树

目录 1. 数据库索引 1.1 索引的概念 1.2 索引的特点 1.3 索引查询对比普通的查询 1.4 索引的操作 1.5 索引的原理 1.6 B树 1.7 B树 1.8 B树的优点 1. 数据库索引 1.1 索引的概念 数据库的索引是一种特殊的数据结构,里面包含着数据表中所有记录的引用&…

jQuery Mobile 面板详解

jQuery Mobile 面板详解 引言 随着移动设备的普及,移动网页开发变得越来越重要。jQuery Mobile 是一个基于 jQuery 的移动网页开发框架,它提供了一套丰富的 UI 组件和主题,使得开发者可以快速构建出美观、响应式的移动网页。在 jQuery Mobile 中,面板(Panel)是一个非常…

Python中的import和from...import有什么区别?

文章目录 前言 一、import导入模块 导入模块并给它一个别名 语法格式 二、from...import导入特定项 1.导入模块中的特定项 2.导入模块中的所有项 2.1 命名空间核污染 2.2 性能影响 总结 前言 在Python编程中,模块和包的导入机制是编写可维护、可扩展代码的核心。深入理解Pyth…

vscode提示“无法使用 compilerPath 解析配置”解决办法

0 问题描述 使用vscode的Remote-SSH插件连接安装在虚拟机上的Windows10进行远程开发时,出现如下提示:无法使用 compilerPath 解析配置:“D:\mingw64\bin\gcc.exe” 所有包含C库头文件的文件都被标红提示错误:1 问题原因 vscode没有设置正确的…

信噪比(Signal-to-Noise Ratio, SNR)详细介绍

信噪比(Signal-to-Noise Ratio, SNR)信噪比(Signal-to-Noise Ratio,SNR)是衡量信号质量的重要参数,表示有用信号的功率与背景噪声功率的比值。SNR在通信、音频处理、视频处理以及其他电子信号处理领域中具有…

Nginx 相关实验(1)

nginx源码编译 本实验采用nginx源码编译的安装方式,需要准备一个tar包,可从nginx官网上下载。 下载地址:nginx: downloadhttps://nginx.org/en/download.html 将下载好的压缩包传到虚拟机中的自定义目录下 [rootwebserver ~]# ls anacond…

【选型】HK32L088 与 STM32F0/L0 系列 MCU 参数对比与选型建议(ST 原厂 vs 国产芯片)(单片机选型主要考虑的参数与因素)

国产 vs ST 单片机在工业控制中的性能对比分析 HK32L088 与 STM32F0/L0 系列 MCU 参数对比与选型建议 工业控制领域 MCU 选型:国产航顺 HK32 与 ST 原厂芯片深入比较 国产 MCU 是否可替代 ST?基于发电机控制应用的深入评估 从数据手册看 MCU 制造工艺差异:HK32L088 vs S…

LLM Prompt与开源模型资源(1)提示词工程介绍

学习材料:https://www.hiascend.com/developer/courses/detail/1935520434893606913学习时长: 预计 30 分钟学习目的: 了解提示工程的定义与作用 熟悉提示工程的关键技术相关概念 掌握基于昇腾适配的大模型提示工程的入门及进阶指南 提示…

kafka与其他消息队列(如 RabbitMQ, ActiveMQ)相比,有什么优缺点?

Kafka、RabbitMQ 和 ActiveMQ 是三种最主流的消息中间件,它们的设计和适用场景有所不同。 我们可以通过一个简单的表格来快速了解它们的核心区别: 核心对比一览特性 / 维度KafkaRabbitMQActiveMQ核心模型分布式、持久化的日志系统 (Dumb Broker / Smart …

Kubernetes架构和部署

k8s组件 master节点:管理节点 管理平面组件 api server : api gateway controller manager scheduler etcd 数据库 worker节点:被管理节点,运行容器 kubelet:k8s agent container runtime:docker,containerd,cri-o kube-proxy:service 网络 कुबेरनेट…

建造者模式及优化

建造者模式是一种创建型设计模式,它将复杂对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。核心思想是指挥者定流程,建造者填细节,通过多个步骤逐步构建对象,并允许灵活组合这些步骤以生成不同配置的…

【09】C++实战篇——C++ 生成静态库.lib 及 C++调用lib,及实际项目中的使用技巧

文章目录1 C 静态库.lib 生成1.1 静态库lib的生成方法和使用方法1.2 创建静态库项目1.3 编写.h 和 .cpp文件1.4 设置 及 生成 DLL2 调用 C 静态库lib2.1 新建LIBtest及测试代码2.2 静态库配置 及代码调用测试3 实际项目中的使用技巧、及通用设置3.1 设置lib输出路径3.2 设置头文…

飞算JavaAI:从写不出代码到丝滑开发,飞算JavaAI把小白从编程深渊捞进了正轨---它都让我怀疑自己是不是多余的!

开篇介绍 对于很多初学者来说,编程是一项既有趣又充满挑战的任务。面对复杂的代码和繁琐的开发流程,常常会感到无从下手。不过,现在有了飞算JavaAI,这一切都将变得简单起来。 它有啥实用功能呢? 比如: …

关于tresos Studio(EB)的MCAL配置之GtmCfg

Generic Time Module通用时钟模块GeneralGtmCfg_DevErrorDetect开发者错误检测开关GtmCfg_DemErrorReporting诊断错误报告开关GtmCfg_VersionInfoApi获取版本信息的接口开关GtmCfg_ConfigSetClockManagementUnitGlobal_Clock_Control_Numerator全局时钟分频器的分子Global_Cloc…

深入探索Weaviate:构建高效AI应用的数据库解决方案

在当今数据驱动的世界中,高效地存储、检索和处理大规模数据成为了AI应用开发的关键挑战。Weaviate作为一个开源的向量搜索引擎,凭借其强大的功能和灵活的架构,正逐渐成为开发者构建智能AI应用的首选工具。本文将深入探讨Weaviate的核心概念、…

【开源】一款开源、跨平台的.NET WPF 通用权限开发框架 (ABP) ,功能全面、界面美观

文章目录一、开源地址二、框架介绍三、技术路线四、适用场景五、功能模块六、框架演示截图一、开源地址 Gihub地址: https://github.com/HenJigg/wpf-abp B站学习视频:https://www.bilibili.com/video/BV1nY411a7T8?spm_id_from333.788.player.switch&…

信创缓存中间件-TongRDS(Redis平替)安装

TongRDS 是由东方通开发的国产 分布式内存数据缓存中间件,功能类似于 Redis,但它是完全自主研发的国产产品,是国内信创的一大重要组件。它兼容 Redis 的接口,能做到应用代码无需改动即可替换使用。TongRDS是没有直接的下载地址的。…

Git链接备用手册

三板斧及其他:git init:初始化git仓库git add . :将所在文件夹中的所有文件加入到暂存区git commit -m 自定义记录信息 :将暂存区中的数据放到Git的仓库(本地)中,并进行记录(自定义&#xff0…

零信任网络概念及在网络安全中的应用

零信任网络概念及在网络安全中的应用 零信任网络(Zero Trust Network)是一种颠覆传统边界安全的架构理念,其核心是**“永不信任,始终验证”**(Never Trust, Always Verify)。它假设网络内外均存在威胁&…