參考
項(xiàng)目 | 描述 |
---|---|
維基百科 | ZIP 格式 |
Python 官方文檔 | zipfile - 使用ZIP存檔 |
搜索引擎 | Google、Bing |
Zip 文件格式規(guī)范 | APPNOTE.TXT |
描述
項(xiàng)目 | 描述 |
---|---|
Python | 3.10.6 |
操作系統(tǒng) | Windows 10 專(zhuān)業(yè)版(x86-64) |
鋪墊
Zip 文件
ZIP 文件格式是一種數(shù)據(jù)壓縮和文檔儲(chǔ)存的文件格式,原名 Deflate,發(fā)明者為菲爾·卡茨(Phil Katz),他于1989年1月公布了該格式的資料。ZIP通常使用后綴名 .zip,它的 MIME 格式為 application/zip。目前,ZIP格式屬于幾種主流的壓縮格式之一,其競(jìng)爭(zhēng)者包括RAR格式以及開(kāi)放源碼的 7z 格式。從性能上比較,RAR 及 7z 格式較 ZIP 格式壓縮率較高,而7-Zip由于提供了免費(fèi)的壓縮工具而逐漸在更多的領(lǐng)域得到應(yīng)用。Microsoft從Windows ME操作系統(tǒng)開(kāi)始內(nèi)置對(duì)zip格式的支持,即使用戶(hù)的電腦上沒(méi)有安裝解壓縮軟件,也能打開(kāi)和制作zip格式的壓縮文件,OS X和流行的Linux操作系統(tǒng)也對(duì)zip格式提供了類(lèi)似的支持。因此如果在網(wǎng)絡(luò)上傳播和分發(fā)文件,zi p格式往往是最常用的選擇。
ZipFile 模塊
zipfile 模塊是 Python 標(biāo)準(zhǔn)庫(kù) 中用于處理 Zip 文件的模塊。它提供了一系列的函數(shù)和類(lèi),可以方便地進(jìn)行 Zip 文件的創(chuàng)建、讀取和解壓縮操作。
Zip 文件格式規(guī)范
APPNOTE.TXT 是一個(gè)關(guān)于 Zip 文件格式的官方規(guī)范文檔,被廣泛引用和使用。文檔提供了詳細(xì)的技術(shù)細(xì)節(jié)和規(guī)范,包括文件格式結(jié)構(gòu)、文件存儲(chǔ)方式、壓縮算法、加密方式、注釋信息、時(shí)間戳等等。
該文檔由 PKWARE 公司發(fā)布,該公司也是 Zip 格式的發(fā)明者和開(kāi)發(fā)者。由于 Zip 文件格式的普及,該規(guī)范文檔被廣泛引用,同時(shí)也影響了其他一些壓縮文件格式的設(shè)計(jì)。因此,對(duì)于使用 Zip 文件的人來(lái)說(shuō),了解該規(guī)范文檔對(duì)于正確地操作 Zip 文件是非常重要的。
PKWARE
PKWARE 是一家總部位于美國(guó)威斯康星州密爾沃基的軟件公司,專(zhuān)門(mén)從事數(shù)據(jù)壓縮和數(shù)據(jù)保護(hù)技術(shù)。該公司是數(shù)據(jù)壓縮標(biāo)準(zhǔn) ZIP 格式的創(chuàng)始人之一,還創(chuàng)建了許多其他壓縮和加密技術(shù),包括 PKZIP、SecureZIP、Smartcrypt 和 PKWARE Data Security 等產(chǎn)品。PKWARE 的產(chǎn)品被廣泛用于數(shù)據(jù)壓縮和加密、數(shù)據(jù)備份和恢復(fù)、數(shù)據(jù)存儲(chǔ)和傳輸?shù)阮I(lǐng)域。
ZipFile
ZipFile 類(lèi)是 zipfile 模塊中最重要的類(lèi)之一,它提供了一系列的方法,用于創(chuàng)建、讀取和解壓縮 Zip 文件。
zipfile.ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=True, compresslevel=None, *, strict_timestamps=True)
file
ZipFile 類(lèi)的 file 參數(shù)用于指定 Zip 文件的名稱(chēng)或路徑。該參數(shù)的值可以是一個(gè)字符串類(lèi)型的文件路徑,也可以是一個(gè)文件對(duì)象。
file 參數(shù)為字符串類(lèi)型的文件路徑
舉個(gè)栗子
from zipfile import ZipFile
# 指定需要被壓縮的文件
FILEPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮與六便士.txt'
# 指定被創(chuàng)建的 Zip 文件所處的路徑
ZIPPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮與六便士.zip'
# 以覆蓋模式(若 ZIP 文件尚不存在,則創(chuàng)建它,若
# Zip 文件已經(jīng)存在,則覆蓋它)打開(kāi) ZIP 文件
fz = ZipFile(ZIPPATH, mode='w')
# 將目標(biāo)文件寫(xiě)入 Zip 壓縮文件中
# write() 的第一個(gè)參數(shù)用于指定需要寫(xiě)入 Zip 壓縮文件中
# 的文件所處的路徑,第二個(gè)參數(shù)用于指定該文件在 Zip 壓縮
# 文件中所處的路徑。
fz.write(FILEPATH, arcname='月亮與六便士.txt')
# 輸出 Zip 壓縮文件中的文件列表
fz.printdir()
# 關(guān)閉 Zip 文件
fz.close()
執(zhí)行效果
File Name Modified Size
月亮與六便士.txt 2023-04-22 16:01:22 315564
file 參數(shù)為一個(gè)文件對(duì)象
ZipFile 與上下文管理器
ZipFile 對(duì)象實(shí)現(xiàn)了上下文管理器接口,因此可以使用 with 語(yǔ)句來(lái)打開(kāi)和關(guān)閉 ZIP 文件。使用上下文管理器可以確保在離開(kāi) with 代碼塊時(shí),文件被自動(dòng)關(guān)閉,避免了因?yàn)榇a異常而導(dǎo)致文件句柄沒(méi)有正確釋放的問(wèn)題。
舉個(gè)栗子
from zipfile import ZipFile
FILEPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮與六便士.txt'
ZIPPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮與六便士.zip'
# 以二進(jìn)制可讀寫(xiě)模式打開(kāi) ZIP 文件,
# 若該文件不存在則創(chuàng)建它;若該文件存在,
# 則覆蓋它。
with open(ZIPPATH, 'wb+') as fo:
with ZipFile(fo, 'w') as fz:
fz.write(FILEPATH, arcname='月亮與六便士')
fz.printdir()
執(zhí)行效果
File Name Modified Size
月亮與六便士 2023-04-22 16:01:22 315564
注:
若使用文件對(duì)象作為 ZipFile() 中 file 參數(shù)的值,那么你需要保證該文件對(duì)象是以二進(jìn)制模式的方式進(jìn)行打開(kāi)的。否則在使用 write() 等方法對(duì) Zip 文件對(duì)象進(jìn)行操作時(shí)可能將引發(fā)錯(cuò)誤。對(duì)此,請(qǐng)參考如下示例:
from zipfile import ZipFile
FILEPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮與六便士.txt'
ZIPPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮與六便士.zip'
# 使用文本模式下的可讀寫(xiě)模式打開(kāi) Zip 文件
with open(ZIPPATH, 'w+') as fo:
with ZipFile(fo, 'w') as fz:
fz.write(FILEPATH, arcname='月亮與六便士')
fz.printdir()
輸出錯(cuò)誤信息
TypeError: write() argument must be str, not bytes
mode
ZipFile 類(lèi)的 mode 參數(shù)用于指定 Zip 文件的打開(kāi)或創(chuàng)建模式,該參數(shù)的值可以是 r、w、x 或 a。
-
r
mode 參數(shù)的 默認(rèn)值 為 r,表示以只讀方式打開(kāi) zip 文件。如果文件不存在,則會(huì)引發(fā)異常 FileNotFoundError。 -
w
以覆蓋方式打開(kāi) Zip 文件。若目標(biāo) Zip 文件已經(jīng)存在,則該文件將被覆蓋。若目標(biāo)文件尚不存在,則創(chuàng)建它。 -
x
以排它方式進(jìn)行 Zip 文件的創(chuàng)建。若文件已經(jīng)存在,則會(huì)引發(fā) FileExistsError 異常。 -
a
以追加方式打開(kāi) Zip 文件。若文件已經(jīng)存在,則在該文件的末尾進(jìn)行文件的寫(xiě)入。若目標(biāo)文件尚不存在,則創(chuàng)建它。
只讀模式與讀或?qū)懙牟僮?/code>
上述模式中,僅當(dāng)將 Zip 文件的模式指定為 r 時(shí),你才不具有對(duì) Zip 文件進(jìn)行寫(xiě)的權(quán)力。在另外三種模式下,你均可以對(duì) Zip 文件進(jìn)行讀或?qū)懙牟僮鳌?/p>
compression
ZipFile 類(lèi)的 compression 參數(shù)用于指定壓縮文件時(shí)使用的壓縮算法,它可以被設(shè)置為以下四個(gè)值之一:ZIP_STORED、ZIP_DEFLATED、ZIP_BZIP2 或 ZIP_LZMA。
項(xiàng)目 | 描述 |
---|---|
ZIP_STORED | 該值為 copression 參數(shù)的 默認(rèn)值。不進(jìn)行任何壓縮,直接存儲(chǔ)原始數(shù)據(jù),通常使用該壓縮算法對(duì)文件進(jìn)行歸檔(將多個(gè)文件歸并為一個(gè)文件,便于文件的存儲(chǔ)與轉(zhuǎn)移)。 |
ZIP_DEFLATED | 指定使用 Deflate 壓縮算法,該算法是 ZIP 文件中最常用的壓縮算法之一。Deflate 算法能夠提供比較高的壓縮率和較快的壓縮和解壓速度,適用于大多數(shù)壓縮場(chǎng)景。 |
ZIP_BZIP2 | 指定使用 Bzip2 壓縮算法。與 Deflate 算法相比,Bzip2算法可以獲得更高的壓縮率,但壓縮和解壓速度較慢,適用于需要獲得更高壓縮率的場(chǎng)景。 |
ZIP_LZMA | 指定使用 LZMA 壓縮算法。LZMA 算法可以提供比 Bzip2 更高的壓縮率,但壓縮和解壓速度更慢,并且需要更多的內(nèi)存。因此,ZIP_LZMA 適用于需要獲得極高壓縮率并且可以承受較慢的壓縮和解壓速度的場(chǎng)景。 |
allowZip64
ZipFile 類(lèi)的 compression 參數(shù)用于指定 Zip 文件在必要情況下是否可以使用 Zip64 格式來(lái)支持超過(guò) 4GB 的文件。
中央結(jié)構(gòu)目錄
中央結(jié)構(gòu)目錄
中央目錄結(jié)構(gòu)是 ZIP 文件格式的一部分,它存儲(chǔ)了 ZIP 文件中包含的所有文件和目錄的元數(shù)據(jù)信息,如文件名、文件屬性、文件的壓縮前和壓縮后的大小等。
Zip 內(nèi)存儲(chǔ)的文件的位置和大小
中央目錄結(jié)構(gòu)還需要記錄 ZIP 文件內(nèi)存儲(chǔ)的文件的位置和大小,這是因?yàn)?ZIP 文件是一種歸檔文件格式,其中的文件通常都經(jīng)過(guò)了壓縮處理,不像普通的文件系統(tǒng)一樣,可以直接訪(fǎng)問(wèn)。
因此,當(dāng)需要解壓縮 ZIP 文件中的某個(gè)文件時(shí),需要知道該文件的存儲(chǔ)位置和大小,以便可以正確地讀取和還原該文件。中央目錄結(jié)構(gòu)中存儲(chǔ)的位置和大小信息可以幫助 ZIP 工具在解壓縮和操作 ZIP 文件時(shí)快速地定位和處理文件,確保 ZIP 文件的正確性和完整性。
完整性
此外,中央目錄結(jié)構(gòu)還可以用于查看 ZIP 文件的內(nèi)容列表,以及檢查 ZIP 文件的完整性和有效性,因?yàn)?中央目錄結(jié)構(gòu)記錄了文件的元數(shù)據(jù)信息,可以用于驗(yàn)證 ZIP 文件中是否存在任何損壞或缺失的文件。
Zip64
在傳統(tǒng)的 Zip 文件格式中,每個(gè) Zip 文件內(nèi)的所有文件和目錄都由一個(gè)中央目錄結(jié)構(gòu)引用,而該結(jié)構(gòu)中存儲(chǔ)文件大小和位置的字段只有 4 個(gè)字節(jié),使用 2^32-1 個(gè)二進(jìn)制位來(lái)記錄信息,所能表示的最大容量位 4GB。因此,傳統(tǒng)的 Zip 文件格式的限制是單個(gè)文件不能超過(guò) 4GB。如果需要支持超過(guò) 4GB 的文件,則需要使用 Zip64 格式。Zip64 格式使用 8 字節(jié)的字段來(lái)存儲(chǔ)文件大小和位置,可以處理更大的文件和歸檔文件。
zipfile.LargeZipFile
倘若你嘗試在沒(méi)有使用 Zip64 擴(kuò)展格式時(shí)壓縮占用空間超過(guò) 4GB 的文件,Python 將拋出如下異常信息并停止壓縮文件。
zipfile.LargeZipFile: Filesize would require ZIP64 extensions
compresslevel
compresslevel 形參控制在將文件進(jìn)行壓縮時(shí)將使用的壓縮等級(jí),壓縮等級(jí)越高,壓縮后文件的體積越小,但壓縮和解壓縮過(guò)程會(huì)相應(yīng)的增加。
注:
-
當(dāng)壓縮算法使用的是 ZIP_STORED 或 ZIP_LZMA 時(shí)指定壓縮等級(jí)將不會(huì)產(chǎn)生任何變化。
-
當(dāng)使用 ZIP_DEFLATED 作為壓縮算法時(shí),壓縮等級(jí)可在 -1 ~ 9 范圍內(nèi);當(dāng)使用 ZIP_BZIP2 作為壓縮算法時(shí),壓縮等級(jí)可在 1 ~ 9 范圍內(nèi)。
-
當(dāng)使用 ZIP_DEFLATED 作為壓縮算法時(shí),其默認(rèn)的壓縮等級(jí)為 -1,該壓縮等級(jí)是速度和壓縮率之間的平衡 (一般相當(dāng)于設(shè)壓縮等級(jí)為 6)。
-
當(dāng)使用 ZIP_DEFLATED 作為壓縮算法時(shí),若將壓縮等級(jí)設(shè)定為 0,則其產(chǎn)生的效果與 ZIP_STORED 無(wú)異。
-
當(dāng)使用 ZIP_BZIP2 作為壓縮算法時(shí),其默認(rèn)的壓縮等級(jí)為 9。
strict_timestamps
strict_timestamps 參數(shù)是用于控制是否允許壓縮早于 1980 年或晚于 2107 年的文件,并且在壓縮這些文件時(shí)是否將時(shí)間戳設(shè)置為最小或最大允許值。
當(dāng) strict_timestamps 參數(shù)為 False 時(shí),zipfile.ZipFile 類(lèi)會(huì)允許壓縮早于 1980 年或晚于 2107 年的文件,并將這些文件的時(shí)間戳設(shè)為 1980 年 1 月 1 日 或 2107 年 12 月 31 日。對(duì)此,請(qǐng)參考如下示例:
import os
from zipfile import ZipFile
# 獲取目標(biāo)文件的訪(fǎng)問(wèn)時(shí)間戳
atime = os.path.getatime('月亮與六便士.txt')
# 將目標(biāo)文件的修改時(shí)間戳設(shè)置為 1970 年 1 月 1 日 8:00:00
os.utime('月亮與六便士.txt', (atime, 0))
FILEPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮與六便士.txt'
ZIPPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮與六便士.zip'
# 嘗試將早于 1980 年的文件寫(xiě)入 Zip 文件中
with open(ZIPPATH, 'wb+') as fo:
with ZipFile(ZIPPATH, 'w', strict_timestamps=False) as fz:
fz.write(FILEPATH, arcname='月亮與六便士.txt')
fz.printdir()
執(zhí)行效果
File Name Modified Size
月亮與六便士.txt 1980-01-01 00:00:00 315564
如果您需要在壓縮文件時(shí)保留原始時(shí)間戳,則可以將 strict_timestamps 參數(shù)設(shè)置為 True(默認(rèn)值),但這可能會(huì)導(dǎo)致無(wú)法壓縮某些文件。對(duì)此,請(qǐng)參考如下示例:
import os
from zipfile import ZipFile
# 獲取目標(biāo)文件的訪(fǎng)問(wèn)時(shí)間戳
atime = os.path.getatime('月亮與六便士.txt')
# 將目標(biāo)文件的修改時(shí)間戳設(shè)置為 1970 年 1 月 1 日 8:00:00
os.utime('月亮與六便士.txt', (atime, 0))
FILEPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮與六便士.txt'
ZIPPATH = r'C:\Users\RedHeart\PycharmProjects\pythonProject\月亮與六便士.zip'
# 嘗試將早于 1980 年的文件寫(xiě)入 Zip 文件中
with open(ZIPPATH, 'wb+') as fo:
with ZipFile(ZIPPATH, 'w') as fz:
fz.write(FILEPATH, arcname='月亮與六便士.txt')
執(zhí)行效果
由于在 strict_timestamps=True 時(shí)嘗試將修改時(shí)間早于 1980 年 1 月 1 日 的文件寫(xiě)入 Zip 文件中,Python 拋出了 ValueError 異常錯(cuò)誤。
ValueError: ZIP does not support timestamps before 1980
注:
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-422325.html
strict_timestamps 針對(duì)的時(shí)間戳為文件的修改時(shí)間戳(文件最后一次修改的時(shí)間所對(duì)應(yīng)的時(shí)間戳信息),在將文件輸入到壓縮包中時(shí),寫(xiě)入的也僅僅為文件的修改時(shí)間戳(文件的創(chuàng)建時(shí)間戳、元數(shù)據(jù)更改時(shí)間戳,訪(fǎng)問(wèn)時(shí)間戳等時(shí)間戳信息并不會(huì)寫(xiě)入 Zip 文件中)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-422325.html
到了這里,關(guān)于解壓你的壓縮:Python ZipFile 實(shí)戰(zhàn)指南(一)ZipFile 類(lèi)和它的參數(shù)們的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!