Python3中使用zipfile進(jìn)行文件的壓縮和解壓縮實(shí)現(xiàn)
一、文件壓縮與解壓縮模塊 zipfile簡介
zipfile 是 Python 標(biāo)準(zhǔn)庫中用于處理 ZIP 壓縮文件的模塊,提供了創(chuàng)建、讀取、寫入、解壓 ZIP 文件的完整功能。它支持多種壓縮算法,無需安裝額外依賴,是處理 ZIP 格式的首選工具。
核心功能與常用類
zipfile.ZipFile 類
這是模塊的核心類,用于創(chuàng)建和操作 ZIP 文件,常用參數(shù):
file:ZIP 文件路徑或文件對象mode:操作模式('r'讀取、'w'創(chuàng)建、'a'追加)compression:壓縮算法(ZIP_STORED無壓縮,ZIP_DEFLATED常用壓縮)
常用操作示例
1. 讀取 ZIP 文件內(nèi)容
import zipfile
with zipfile.ZipFile('example.zip', 'r') as zf:
# 查看壓縮包內(nèi)所有文件
print(zf.namelist()) # 返回文件名列表
# 查看文件信息(大小、壓縮率等)
for info in zf.infolist():
print(f"文件名: {info.filename}, 原始大小: {info.file_size}, 壓縮后: {info.compress_size}")
2. 解壓 ZIP 文件
import zipfile
with zipfile.ZipFile('example.zip', 'r') as zf:
# 解壓所有文件到指定目錄(默認(rèn)當(dāng)前目錄)
zf.extractall(path='解壓目錄')
# 解壓單個(gè)文件
zf.extract('文件路徑/文件名.txt', path='單個(gè)文件解壓目錄')
3. 創(chuàng)建 ZIP 文件(壓縮文件/文件夾)
import zipfile
import os
# 壓縮單個(gè)文件
with zipfile.ZipFile('output.zip', 'w', zipfile.ZIP_DEFLATED) as zf:
zf.write('file1.txt', arcname='file1.txt') # arcname 可指定壓縮包內(nèi)文件名
# 壓縮文件夾(含子目錄)
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)
# 保持相對路徑,確保文件夾結(jié)構(gòu)
arcname = os.path.relpath(file_path, os.path.dirname(folder_path))
zf.write(file_path, arcname=arcname)
zip_folder('需要壓縮的文件夾', 'result.zip')
4. 向現(xiàn)有 ZIP 追加文件
import zipfile
with zipfile.ZipFile('existing.zip', 'a', zipfile.ZIP_DEFLATED) as zf:
zf.write('new_file.txt') # 追加新文件到已有壓縮包
注意事項(xiàng)
- 壓縮算法:
ZIP_DEFLATED需要系統(tǒng)支持 zlib 庫(通常默認(rèn)支持),否則需使用無壓縮的ZIP_STORED。 - 路徑處理:壓縮文件夾時(shí)需通過
arcname控制路徑,避免生成冗余的絕對路徑。 - 大型文件:處理大文件時(shí)建議使用
with語句,確保資源正確釋放。
通過 zipfile 模塊,可輕松實(shí)現(xiàn) ZIP 文件的全流程管理,滿足日常壓縮/解壓需求。
二、案例實(shí)操
2.0 測試文件準(zhǔn)備
原始結(jié)構(gòu)為:
dir_level_1/
├── file1.txt
├── subfolder1/
│ └── file2.txt
└── subfolder2/
└── subsubfolder/
└── file3.txt
程序設(shè)計(jì)初衷:
將目錄“dir_level_1”下所有的文件、子文件夾、子文件夾下的文件,安裝原先的層次結(jié)構(gòu),壓縮為一個(gè)文件“dir_level_1.zip”。
2.1 綜合案例:實(shí)現(xiàn)文件壓縮、查看壓縮內(nèi)容、解壓
"""
14-5 文件壓縮與解壓模塊-zipFile
操作系統(tǒng)提供將一般文件或目錄進(jìn)行壓縮的功能,壓縮后的擴(kuò)展名是zip,
Python有 zipFile 模塊也可以將文件或目錄壓縮以及解壓縮。
壓縮文件或目錄:
zipfile.ZipFile(file_name, mode='w', compression=ZIP_DEFLATED)
file_name: 壓縮文件的名稱
mode: 壓縮文件的模式,w表示寫入,a表示追加
compression: 壓縮算法,ZIP_DEFLATED表示使用 deflate 算法進(jìn)行壓縮
解壓文件或目錄:
zipfile.ZipFile(file_name, mode='r')
14-5-1 執(zhí)行文件或目錄的壓縮
說明:
執(zhí)行文件壓縮前首先要使用ZipFile()方法創(chuàng)建一個(gè)壓縮后的文件對象,在
這個(gè)方法中另外要加上“w”參數(shù),表明未來是提供 write() 方法寫入文件。
語法:
fileZip = zipfile.ZipFile('out.zip', mode='w',compression=ZIP_DEFLATED)
上述fileZip和out.zip皆可以自由命名,fileZip是壓縮文件對象,代表的out.zip,
未來將被壓縮的文件數(shù)據(jù)寫入到此對象中,就可以將結(jié)果保存為 out.zip 文件了。
注意:
1、雖然ZipFile()無法執(zhí)行整個(gè)目錄的壓縮,不過可以使用循環(huán)(遞歸)方式將目錄底下的文件或文件夾進(jìn)行壓縮,即可達(dá)到壓縮整個(gè)目錄的目的。
詳見:c14-5.2_zip_with_hierarchy.py
14-5-2 讀取zip文件
說明:
1、listZipInfo.namelist() : 返回zip文件中所有文件的名稱列表(List)。
2、listZipInfo.infolist() : 返回各個(gè)元素的屬性,如文件名、文件大小、壓縮結(jié)果大小、文件時(shí)間、文件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 執(zhí)行文件或目錄的壓縮 -----------------------")
# ch14_41.py : 將當(dāng)前工作目錄下的 dir_level_1 目錄壓縮,壓縮結(jié)果存儲在 dir_level_1.zip 文件中.
"""
代碼說明:
這行代碼的作用是遍歷dir_level_1目錄下的所有文件和目錄(但不包括子目錄中的內(nèi)容)。
具體解釋如下:
glob.glob('dir_level_1/*'):
glob是一個(gè)用于匹配文件路徑的模塊,支持Unix shell-style的通配符
dir_level_1/*表示匹配dir_level_1目錄下的所有文件和目錄(一級內(nèi)容)
這個(gè)表達(dá)式會(huì)返回一個(gè)包含所有匹配路徑的列表
for name in ...:
遍歷glob返回的每個(gè)文件/目錄路徑
根據(jù)對項(xiàng)目文件結(jié)構(gòu)的查看,dir_level_1目錄包含以下內(nèi)容:
- 多個(gè)文件:2.docx、out14_27.txt等
- 一個(gè)子目錄:dir_level_2(包含1.docx和1.txt)
需要注意的是,dir_level_1/*這種模式只會(huì)匹配dir_level_1目錄下的直接內(nèi)容,不會(huì)遞歸匹配子目錄中的文件。所以在示例中,它會(huì)匹配到2.docx、out14_27.txt等文件以及 dir_level_2目錄本身,但不會(huì)匹配dir_level_2 目錄中的1.docx和1.txt。
在代碼中,這些匹配到的文件和目錄會(huì)被逐一添加到dir_level_1.zip壓縮文件中。
"""
import zipfile
import glob, os
fileZip = zipfile.ZipFile('dir_level_1.zip', 'w')
for name in glob.glob('dir_level_1/*'): # 遍歷指定目錄下的所有文件,但測試下來,僅會(huì)壓縮dir_level_1下首層文件及文件夾,而不會(huì)將二層dir_level_1\dir_level_2下的文件(如1.txt,1.docx)壓縮進(jìn)dir_level_1.zip中
fileZip.write(name, os.path.basename(name), zipfile.ZIP_DEFLATED) # 參數(shù)3為壓縮方式
fileZip.close()
print("----------------------- 案例-14-5-2 讀取zip文件 -----------------------")
# ch14_41.py :
import zipfile
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, '\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 : 將程序?qū)嵗?ch14_41.py 所建立的 dir_level_1.zip 解壓縮,同時(shí)將解壓結(jié)果存入 out43 目錄
import zipfile
fileUnZip = zipfile.ZipFile("dir_level_1.zip", "r")
fileUnZip.extractall("out43")
fileUnZip.close()
2.2 壓縮方法優(yōu)化-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壓縮進(jìn)來,而只會(huì)將dir_level_2文件夾本身壓縮進(jìn)來,未達(dá)到程序?qū)崿F(xiàn)功能的初衷。
改進(jìn)說明:
要解決級聯(lián)壓縮文件夾(包含子文件夾結(jié)構(gòu))的問題,需要遞歸遍歷文件夾中的所有文件,并保持原有的目錄結(jié)構(gòu)。
代碼解釋
要解決級聯(lián)壓縮文件夾(包含子文件夾結(jié)構(gòu))的問題,需要遞歸遍歷文件夾中的所有文件,并保持原有的目錄結(jié)構(gòu)。以下是實(shí)現(xiàn)這一功能的完整代碼:
代碼清單:
zip_recursive.py
import zipfile
import os
def zip_directory(folder_path, zip_file):
"""
遞歸壓縮文件夾及其子目錄中的所有文件
參數(shù):
folder_path (str): 要壓縮的文件夾路徑
zip_file (zipfile.ZipFile): 已打開的ZipFile對象
"""
# 遍歷文件夾中的所有內(nèi)容
for item in os.listdir(folder_path):
item_path = os.path.join(folder_path, item)
# 如果是文件,直接添加到壓縮包
if os.path.isfile(item_path):
# 計(jì)算相對路徑,保持目錄結(jié)構(gòu)
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"
# 創(chuàng)建并打開zip文件
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
zip_directory(root_folder, zipf)
print(f"壓縮完成,文件保存為: {zip_path}")
代碼解析:
核心函數(shù):
zip_directory函數(shù)通過遞歸方式處理文件夾及其子文件夾- 對于文件:直接添加到壓縮包,并通過
arcname參數(shù)保持相對路徑 - 對于子文件夾:遞歸調(diào)用自身處理
- 對于文件:直接添加到壓縮包,并通過
關(guān)鍵技術(shù)點(diǎn):
- 使用
os.path.relpath計(jì)算文件相對路徑,確保壓縮包內(nèi)保持原有的目錄結(jié)構(gòu) - 使用
with語句管理 ZipFile 對象,確保資源正確釋放 - 使用
ZIP_DEFLATED模式創(chuàng)建壓縮的zip文件(而不是僅存儲)
- 使用
使用方法:
- 將
root_folder設(shè)置為根文件夾路徑(如 “dir_level_1”) - 運(yùn)行程序后,會(huì)將 dir_level_1 下所有文件、子目錄(包括 dir_level_2 中的 1.docx)完整壓縮到 dir_level_1.zip 中
- 將
這樣處理后,壓縮包內(nèi)會(huì)完整保留原有的文件夾層次結(jié)構(gòu),而不是僅壓縮最內(nèi)層的文件夾。
2.3 壓縮方法優(yōu)化-V2版本
V1版缺陷:
這樣實(shí)現(xiàn)不能忠實(shí)的反饋原文件夾結(jié)構(gòu),本意是希望原先dir_level_1下的文件夾和文件都壓縮至dir_level_1目錄下,而目前的代碼實(shí)現(xiàn)的邏輯是dir_level_1下的文件是放在了dir_level_1下,但dir_level_1下的文件夾,如 dir_level_2 卻沒有放在dir_level_1下,而是與dir_level_1平級了。
改進(jìn)說明:
要解決文件夾結(jié)構(gòu)忠實(shí)還原的問題,關(guān)鍵在于正確設(shè)置壓縮包內(nèi)的相對路徑。以下是改進(jìn)后的代碼,確保所有文件和子文件夾都正確嵌套在根目錄下。
核心改進(jìn)點(diǎn):
- 明確將根文件夾名稱(
root_basename)作為壓縮包內(nèi)的頂級目錄 - 所有文件和子文件夾都通過
os.path.join(root_basename, ...)構(gòu)建路徑,確保嵌套在根目錄下 - 使用
zip_subdirectory專門處理子文件夾,保持完整的層級關(guān)系
- 明確將根文件夾名稱(
結(jié)構(gòu)保證:
假設(shè)原始結(jié)構(gòu)為:dir_level_1/ ├── file1.txt ├── subfolder1/ │ └── file2.txt └── subfolder2/ └── subsubfolder/ └── file3.txt壓縮后在zip文件中會(huì)保持完全相同的結(jié)構(gòu):
dir_level_1/ ├── file1.txt ├── subfolder1/ │ └── file2.txt └── subfolder2/ └── subsubfolder/ └── file3.txt使用方法:
- 將
root_folder設(shè)置為根目錄(如 “dir_level_1”) - 運(yùn)行程序后,所有內(nèi)容都會(huì)被正確壓縮到該根目錄下,不會(huì)出現(xiàn)平級問題
- 將
這種實(shí)現(xiàn)方式能精確還原原始文件夾的層級結(jié)構(gòu),確保子文件夾都正確嵌套在指定的根目錄下。
代碼清單:
zip_with_hierarchy.py
import zipfile
import os
def zip_directory(root_folder, zip_file):
"""
遞歸壓縮指定文件夾,保持完整的目錄結(jié)構(gòu)
參數(shù):
root_folder (str): 要壓縮的根文件夾路徑
zip_file (zipfile.ZipFile): 已打開的ZipFile對象
"""
# 獲取根文件夾的基本名稱,作為壓縮包內(nèi)的頂級目錄
root_basename = os.path.basename(root_folder)
# 遍歷根文件夾中的所有內(nèi)容
for item in os.listdir(root_folder):
item_path = os.path.join(root_folder, item)
# 構(gòu)建壓縮包內(nèi)的相對路徑,確保所有內(nèi)容都在根文件夾名下
arcname = os.path.join(root_basename, item)
if os.path.isfile(item_path):
# 添加文件,使用構(gòu)建的相對路徑
zip_file.write(item_path, arcname=arcname)
print(f"已添加文件: {arcname}")
elif os.path.isdir(item_path):
# 遞歸處理子文件夾,同時(shí)保持目錄結(jié)構(gòu)
zip_subdirectory(item_path, zip_file, root_basename)
def zip_subdirectory(subfolder_path, zip_file, root_basename):
"""遞歸處理子文件夾,保持相對路徑結(jié)構(gòu)"""
# 獲取當(dāng)前子文件夾相對于根文件夾的路徑
rel_path = os.path.relpath(subfolder_path, os.path.dirname(subfolder_path))
# 構(gòu)建壓縮包內(nèi)的完整路徑
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"錯(cuò)誤: 文件夾 '{root_folder}' 不存在")
else:
# 創(chuàng)建并打開zip文件,使用DEFLATED模式進(jìn)行壓縮
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
zip_directory(root_folder, zipf)
print(f"壓縮完成,文件保存為: {zip_path}")
到此這篇關(guān)于Python3中使用zipfile進(jìn)行文件的壓縮和解壓縮實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python3 zipfile壓縮和解壓縮內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺析Python與Mongodb數(shù)據(jù)庫之間的操作方法
這篇文章主要介紹了Python與Mongodb數(shù)據(jù)庫之間的操作,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07
python 設(shè)置xlabel,ylabel 坐標(biāo)軸字體大小,字體類型
這篇文章主要介紹了python 設(shè)置xlabel,ylabel 坐標(biāo)軸字體大小,字體類型,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
使用Python和OpenCV檢測圖像中的物體并將物體裁剪下來
這篇文章主要介紹了使用Python和OpenCV檢測圖像中的物體并將物體裁剪下來,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
使用Python實(shí)現(xiàn)監(jiān)測APP的使用流量
這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)監(jiān)測APP的使用流量,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2026-04-04
python opencv實(shí)現(xiàn)旋轉(zhuǎn)矩形框裁減功能
這篇文章主要為大家詳細(xì)介紹了python opencv實(shí)現(xiàn)旋轉(zhuǎn)矩形框裁減功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Python數(shù)據(jù)封裝與私有屬性應(yīng)用案例
本文介紹了數(shù)據(jù)封裝在面向?qū)ο缶幊讨械闹匾?以及Python中實(shí)現(xiàn)數(shù)據(jù)封裝的多種方法,包括命名約定、名稱修飾和使用@property裝飾器,通過實(shí)際例子展示了如何在銀行賬戶系統(tǒng)中應(yīng)用這些技術(shù),感興趣的朋友跟隨小編一起看看吧2026-01-01
Python常見報(bào)錯(cuò)解決方案總結(jié)(新手拯救指南)
我們再使用python難免會(huì)出現(xiàn)各種各樣的報(bào)錯(cuò),下面這篇文章主要給大家介紹了關(guān)于Python常見報(bào)錯(cuò)解決方案的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
Python真題案例之小學(xué)算術(shù)?階乘精確值?孿生素?cái)?shù)?6174問題詳解
這篇文章主要介紹了python實(shí)操案例練習(xí),本文給大家分享的案例中主要任務(wù)有小學(xué)生算術(shù)、階乘的精確值、孿生素?cái)?shù)、6174問題,需要的小伙伴可以參考一下2022-03-03

