一文詳解Python加解壓文件gzip庫(kù)的操作
一、gzip
GZIP概念
Gzip是若干種文件壓縮程序的簡(jiǎn)稱(chēng),通常指GNU計(jì)劃的實(shí)現(xiàn),此處的gzip代表GNU zip。也經(jīng)常用來(lái)表示gzip這種文件格式。
GZIP最早由Jean-loup Gailly和Mark Adler創(chuàng)建,用于UNⅨ系統(tǒng)的文件壓縮。我們?cè)贚inux中經(jīng)常會(huì)用到后綴為.gz的文件,它們就是GZIP格式的?,F(xiàn)今已經(jīng)成為Internet 上使用非常普遍的一種數(shù)據(jù)壓縮格式,或者說(shuō)一種文件格式。
HTTP協(xié)議的GZIP編碼是一種用來(lái)改進(jìn)WEB應(yīng)用程序性能的技術(shù)。大流量的WEB站點(diǎn)常常使用GZIP壓縮技術(shù)來(lái)讓用戶(hù)感受更快的速度。這一般是指WWW服務(wù)器中安裝的一個(gè)功能,當(dāng)有人來(lái)訪(fǎng)問(wèn)這個(gè)服務(wù)器中的網(wǎng)站時(shí),服務(wù)器中的這個(gè)功能就將網(wǎng)頁(yè)內(nèi)容壓縮后傳輸?shù)絹?lái)訪(fǎng)的電腦瀏覽器中顯示出來(lái).一般對(duì)純文本內(nèi)容可壓縮到原大小的40%.這樣傳輸就快了,效果就是你點(diǎn)擊網(wǎng)址后會(huì)很快的顯示出來(lái).當(dāng)然這也會(huì)增加服務(wù)器的負(fù)載. 一般服務(wù)器中都安裝有這個(gè)功能模塊的。
文件格式
gzip的基礎(chǔ)是DEFLATE,DEFLATE是LZ77與哈夫曼編碼的一個(gè)組合體。盡管這種文件格式允許多個(gè)這樣的數(shù)據(jù)拼接在一起,在解壓時(shí)也能認(rèn)出它們是拼接在一起的數(shù)據(jù),但通常gzip僅用來(lái)壓縮單個(gè)文件。多個(gè)文件的壓縮歸檔通常是首先將這些文件合并成一個(gè)tar文件,然后再使用gzip進(jìn)行壓縮,最后生成的.tar.gz或者.tgz文件就是所謂的“tar壓縮包”或者“tarball”。
注意不要將gzip和ZIP壓縮格式混淆。ZIP也使用DEFLATE算法,而且可移植性更好,不需要一個(gè)外部的歸檔工具就可以包容多個(gè)文件。但是,由于ZIP對(duì)每個(gè)文件進(jìn)行單獨(dú)壓縮而沒(méi)有利用文件間的冗余信息(即固實(shí)壓縮),所以ZIP的壓縮率會(huì)稍遜于tar壓縮包。
二、Python gzip庫(kù)
gzip庫(kù)是python的標(biāo)準(zhǔn)庫(kù),此模塊提供的簡(jiǎn)單接口幫助用戶(hù)壓縮和解壓縮文件,功能類(lèi)似于 GNU 應(yīng)用程序 gzip 和 gunzip。數(shù)據(jù)壓縮由 zlib
模塊提供。
gzip模塊提供 GzipFile
類(lèi)和 open()
、compress()
、decompress()
幾個(gè)便利的函數(shù)。GzipFile
類(lèi)可以讀寫(xiě) gzip 格式的文件,還能自動(dòng)壓縮和解壓縮數(shù)據(jù),這讓操作壓縮文件如同操作普通的 file object 一樣方便。
注意,此模塊不支持部分可以被 gzip 和 gunzip 解壓的格式,如利用 compress 或 pack 壓縮所得的文件。
gzip.open
gzip.open( filename, mode='rb', compresslevel=9, encoding=None, errors=None, newline=None)
以二進(jìn)制方式或者文本方式打開(kāi)一個(gè) gzip 格式的壓縮文件,返回一個(gè) file object。
參數(shù)說(shuō)明:
filename:參數(shù)可以是一個(gè)實(shí)際的文件名(一個(gè)str 對(duì)象或者bytes對(duì)象), 或者是一個(gè)用來(lái)讀寫(xiě)的已存在的文件對(duì)象。
mode:參數(shù)可以是二進(jìn)制模式'r'
, 'rb'
, 'a'
, 'ab'
, 'w'
, 'wb'
, 'x'
or 'xb'
, 或者是文本模式 'rt'
, 'at'
, 'wt'
, or 'xt'
。默認(rèn)值是 'rb'
。它的默認(rèn)值是'r',表示以文本模式打開(kāi)閱讀。其他常見(jiàn)的值有:'w'用于寫(xiě)入(如果文件已經(jīng)存在,則截?cái)嗨?#39;x'用于獨(dú)占創(chuàng)建,'a'用于追加(在一些Unix系統(tǒng)上,這意味著所有的寫(xiě)入都追加到文件的末尾,不管當(dāng)前的尋址位置如何)。在文本模式下,如果沒(méi)有指定編碼,使用的編碼是與平臺(tái)有關(guān)的:調(diào)用locale.getpreferredencoding(False)來(lái)獲得當(dāng)前的locale編碼。(對(duì)于讀寫(xiě)原始字節(jié),使用二進(jìn)制模式,不指定編碼。) 可用的模式。
compresslevel參數(shù)是從0到9的整數(shù),壓縮等級(jí); 壓縮格式分類(lèi)。
import gzip # 創(chuàng)建一個(gè)gzip文件 content = "Hello world!" f = gzip.open('file.txt.gz', 'wb') f.write(content.encode()) f.close()
其中'wb'就是寫(xiě)入,若沒(méi)有該路徑文件將會(huì)自動(dòng)生成一個(gè)文件。
gzip.GzipFile壓縮和解壓
class gzip.GzipFile( filename=None, mode=None, compresslevel=9, fileobj=None, mtime=None)
GzipFile
類(lèi)的構(gòu)造器支持 truncate()
的異常,與 file object 的大多數(shù)方法非常相似。fileobj和 filename至少有一個(gè)不為空。
新的實(shí)例基于 fileobj,它可以是一個(gè)普通文件,一個(gè) io.BytesIO
對(duì)象,或者任何一個(gè)與文件相似的對(duì)象。當(dāng) filename 是一個(gè)文件對(duì)象時(shí),它的默認(rèn)值是 None
。
當(dāng) fileobj 為 None
時(shí), filename 參數(shù)只用于 gzip 文件頭中,這個(gè)文件有可能包含未壓縮文件的源文件名。如果文件可以被識(shí)別,默認(rèn) fileobj 的文件名;否則默認(rèn)為空字符串,在這種情況下文件頭將不包含源文件名。
需要注意的是,文件默認(rèn)使用二進(jìn)制模式打開(kāi)。如果要以文本模式打開(kāi)文件一個(gè)壓縮文件,應(yīng)該使用 open()
方法(或者使用 io.TextIOWrapper
包裝 GzipFile
)。
調(diào)用 GzipFile
的 close()
方法不會(huì)關(guān)閉 fileobj,可以將一個(gè) io.BytesIO
對(duì)象作為 fileobj,也可以使用 io.BytesIO
的 getvalue()
方法從內(nèi)存緩存中恢復(fù)數(shù)據(jù)。
GzipFile
支持 io.BufferedIOBase
類(lèi)的接口, 包括迭代和 with
語(yǔ)句。只有 truncate()
方法沒(méi)有實(shí)現(xiàn)。
import gzip # 創(chuàng)建GzipFile實(shí)例 zf = gzip.GzipFile('file_1.txt.gz', mode = 'wb') contents = "Hello world!Friend!" zf.write(contents.encode()) # 寫(xiě)文件 zf.close() # 關(guān)閉
gzip.comress()壓縮數(shù)據(jù)
另外一種方法是用gzip.comress()方法將從文件中讀出的數(shù)據(jù)進(jìn)行壓縮,再將壓縮后的數(shù)據(jù)寫(xiě)入到文件中。
import gzip contents = "Hello world!Friend!" pf = gzip.open('file_2.txt.gz', 'wb') data_comp = gzip.compress(contents.encode()) # 壓縮數(shù)據(jù) pf.write(data_comp) # 寫(xiě)文件 pf.close() # 關(guān)閉
從壓縮文件看該方法和前2種效果是一樣的。
下面這種方法更簡(jiǎn)便、更安全:
import gzip with open('file_3.txt.gz', 'wb') as pw, open('file_3.txt','rb') as pr: pw.write(gzip.compress(pr.read()) )
解壓數(shù)據(jù)
第一種
直接open就可以了:
import gzip zip_filename = 'file.txt.gz' with open('./file_1.txt','wb') as pw: zf = gzip.open(zip_filename, mode = 'rb') pw.write(zf.read()) # 寫(xiě)文件 zf.close()
第二種
和壓縮方法的順序是一樣的,使用GzipFile就好了:
zip_filename = 'file_2.txt.gz' with open('./file_2.txt','wb') as pw: zf = gzip.GzipFile(zip_filename, mode = 'rb') pw.write(zf.read()) # 寫(xiě)文件 zf.close()
第三種
zip_filename = 'file_3.txt.gz' with open(zip_filename, 'rb') as pr, open('./file_3.txt','wb') as pw: pw.write(gzip.decompress(pr.read()) )
集體解壓
import os import gzip def unzip_gz_file(path, new_path): count = 0 try: for f_path in os.listdir(path): if '.gz' in f_path: try: with gzip.GzipFile(fileobj=open(path + "/" + f_path, 'rb'), mode='rb') as g: with open(new_path + "/" + f_path.replace(".gz", ""), "wb") as f: f.write(g.read()) print(count, f"文件{f_path} 解壓完成...") except Exception as e: print(f_path, e) count += 1 except Exception as e: print(e) else: print("文件全部解壓完成!") path = './' new_path = './unzip_file' unzip_gz_file(path, new_path)
到此這篇關(guān)于一文詳解Python加解壓文件gzip庫(kù)的操作的文章就介紹到這了,更多相關(guān)Python gzip庫(kù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 對(duì)象真假值的實(shí)例(哪些視為False)
這篇文章主要介紹了python 對(duì)象真假值的實(shí)例(哪些視為False),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12Scrapy模擬登錄趕集網(wǎng)的實(shí)現(xiàn)代碼
這篇文章主要介紹了Scrapy模擬登錄趕集網(wǎng)的實(shí)現(xiàn)代碼,本文通過(guò)代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07圖文詳解感知機(jī)算法原理及Python實(shí)現(xiàn)
感知機(jī)是二類(lèi)分類(lèi)的線(xiàn)性分類(lèi)模型,其輸入為實(shí)例的特征向量,輸出為實(shí)例的類(lèi)別(取+1和-1二值)。本文將為大家詳細(xì)講講感知機(jī)算法的原理及實(shí)現(xiàn),需要的可以參考一下2022-08-08Python3實(shí)現(xiàn)并發(fā)檢驗(yàn)代理池地址的方法
這篇文章主要介紹了Python3實(shí)現(xiàn)并發(fā)檢驗(yàn)代理池地址的方法,實(shí)例分析了Python3基于線(xiàn)程的代理檢驗(yàn)操作相關(guān)技巧,需要的朋友可以參考下2016-09-09Python強(qiáng)化練習(xí)之PyTorch opp算法實(shí)現(xiàn)月球登陸器
在面向?qū)ο蟪霈F(xiàn)之前,我們采用的開(kāi)發(fā)方法都是面向過(guò)程的編程(OPP)。面向過(guò)程的編程中最常用的一個(gè)分析方法是“功能分解”。我們會(huì)把用戶(hù)需求先分解成模塊,然后把模塊分解成大的功能,再把大的功能分解成小的功能,整個(gè)需求就是按照這樣的方式,最終分解成一個(gè)一個(gè)的函數(shù)2021-10-10淺談django開(kāi)發(fā)者模式中的autoreload是如何實(shí)現(xiàn)的
下面小編就為大家?guī)?lái)一篇淺談django開(kāi)發(fā)者模式中的autoreload是如何實(shí)現(xiàn)的。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08使用python統(tǒng)計(jì)文件行數(shù)示例分享
當(dāng)文件的尺寸非常大的時(shí)候(10G之上吧),想知道行數(shù)是個(gè)問(wèn)題,提供一個(gè)使用python統(tǒng)計(jì)文件行數(shù)的示例,需要的朋友可以參考下2014-02-02Python?socket如何解析HTTP請(qǐng)求內(nèi)容
這篇文章主要介紹了Python?socket如何解析HTTP請(qǐng)求內(nèi)容,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02