Python解壓ZIP、RAR等常用壓縮格式的方法


解壓大殺器

首先祭出可以應對多種壓縮包格式的python庫:patool。如果平時只用基本的解壓、打包等操作,也不想詳細了解各種壓縮格式對應的python庫,patool應該是個不錯的選擇。
patool庫支持的格式包括:

7z (.7z, .cb7), ACE (.ace, .cba), ADF (.adf), ALZIP (.alz), APE (.ape), AR (.a), ARC (.arc), ARJ (.arj), BZIP2 (.bz2), CAB (.cab), COMPRESS (.Z), CPIO (.cpio), DEB (.deb), DMS (.dms), FLAC (.flac), GZIP (.gz), ISO (.iso), LRZIP (.lrz), LZH (.lha, .lzh), LZIP (.lz), LZMA (.lzma), LZOP (.lzo), RPM (.rpm), RAR (.rar, .cbr), RZIP (.rz), SHN (.shn), TAR (.tar, .cbt), XZ (.xz), ZIP (.zip, .jar, .cbz) and ZOO (.zoo)

patool的基本使用方法:

import patoolib
# 解壓縮
patoolib.extract_archive("archive.zip", outdir="/tmp")
# 測試壓縮包是否完整
patoolib.test_archive("dist.tar.gz", verbosity=1)
# 列出壓縮包內的文件
patoolib.list_archive("package.deb")
# 創建壓縮包
patoolib.create_archive("/path/to/myfiles.zip", ("file1.txt", "dir/"))
# 比較壓縮包內文件的差異
patoolib.diff_archives("release1.0.tar.gz", "release2.0.zip")
# 搜索
patoolib.search_archive("def urlopen", "python3.3.tar.gz")
# 修改壓縮包的壓縮格式
patoolib.repack_archive("linux-2.6.33.tar.gz", "linux-2.6.33.tar.bz2")

但是,patool的正常運行依賴於其他解壓軟件,例如,我平時用patool來解壓文件時它主要調用了我電腦的7z、Rtools兩個程序,如果電腦上沒有能夠處理相應壓縮文件的軟件,則會報錯:

patoolib.util.PatoolError: could not find an executable program to extract format rar; candidates are (rar,unrar,7z)

另外,patool無法處理具有密碼保護的壓縮文件。
與patool類似的庫還有pyunpackeasy-extract:pyunpack庫依賴zipfile和patool,支持兩庫所支持的所有壓縮格式,需提前安裝;easy-extract庫依賴解壓軟件unrar、7z、par2,需提前安裝,同樣支持多種解壓格式。

常見壓縮格式的處理

如果電腦上並未安裝相應的壓縮軟件,只想使用python進行壓縮解壓操作,可以使用其他的下面來具體介紹幾種常見的

zip格式

可以處理zip格式的python庫包括python標准庫zipfile,以及第三方庫python-archive等,下面主要介紹一下zipfile庫的基本使用方法:
首先創建ZipFile對象:

# 導入ZipFile類
from zipfile import ZipFile

# ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, compresslevel=None)
# 默認模式是讀取,該模式提供read(), readline(), readlines(), __iter__(), __next__()等方法

解壓縮文件包,解壓函數共有兩個:extract()、extractall(),前者可解壓單個文件,默認解壓至當前目錄,后者可批量解壓多個文件,默認解壓所有文件。extract()、extractall()均有參數pwd,可處理具有密碼的壓縮包。

with ZipFile('test.zip') as myzip:
    myzip.extract(member='1.txt',path='tmp')
    myzip.extractall(path='tmp',members=['1.txt','2.txt'],pwd='password')

制作壓縮文件:zipfile共有四種壓縮文件的方法分別為:zipfile.ZIP_STORED(默認)、zipfile.ZIP_DEFLATED、zipfile.ZIP_BZIP2、zipfile.ZIP_LZMA

# 添加文件的mode有'w', 'a', 'x'
# 'w'表示覆蓋或寫入一個新文件;'a'表示在已有文件后追加;'x'表示新建文件並寫入。
# 在三種mode下,如果未寫入認識數據,則會生成空的ZIP文件。
with ZipFile('test.zip',mode='w') as myzip:
	for file in ['1.txt', '2.txt']: # 需壓縮的文件列表
		myzip.write(file,compress_type=zipfile.ZIP_DEFLATED)

壓縮整個文件夾

# 方法一
def addToZip(zf, path, zippath):
    if os.path.isfile(path):
        zf.write(path, zippath, zipfile.ZIP_DEFLATED)  # 以zlib壓縮方法寫入文件
    elif os.path.isdir(path):
        if zippath:
            zf.write(path, zippath)
        for nm in os.listdir(path):
            addToZip(zf, os.path.join(path, nm), os.path.join(zippath, nm))
with zipfile.ZipFile('tmp4.zip', 'w') as zip_file:
    addToZip(zip_file,'tmp','tmp')
    
#方法二
class ZipFolder:
    def toZip(self, file, zipfilename):
    	# 首先創建zipfile對象
        with zipfile.ZipFile(zipfilename, 'w') as zip_file:
            if os.path.isfile(file):  # 判斷寫入的是文件還是文件夾,是文件的話直接寫入
                zip_file.write(file)
            else:  # 否則調用寫入文件夾的函數assFolderToZip()
                self.addFolderToZip(zip_file, file)

    def addFolderToZip(self, zip_file, folder):
        for file in os.listdir(folder):  # 依次遍歷文件夾內的文件
            full_path = os.path.join(folder, file)
            if os.path.isfile(full_path): # 判斷是文件還是文件夾,是文件的話直接寫入
                print('File added: ', str(full_path))
                zip_file.write(full_path)
            elif os.path.isdir(full_path): 
            # 如果是文件夾的話再次調用addFolderToZip函數,寫入文件夾
                print('Entering folder: ', str(full_path))
                self.addFolderToZip(zip_file, full_path)
directory = 'tmp'	# 需壓縮的文件目錄
zipfilename = 'tmp1.zip'	#壓縮后的文件名
ZipFolder().toZip(directory, zipfilename)

rar格式

rar格式沒有對應的python標准庫,需依賴第三方庫rarfilepython-unrarpyUnRAR2等,上述庫的共同點在於依賴RARLAB的UnRAR library的支持,下面主要介紹一下rarfile庫:

  1. 安裝及其配置
    安裝命令:
    pip install rarfile
    
    但配置頗費了些時間。首先要下載安裝UnRAR。因為我的電腦操作系統是Windows,所以去RARLAB官網下載UnRarDLL即可,安裝至默認路徑C:\Program Files (x86)\UnrarDLL。
    然后是添加環境變量,先是將C:\Program Files (x86)\UnrarDLL\x64(我的系統是64位)添加至系統變量中的Path變量(計算機右鍵>屬性>高級系統設置>高級 >環境變量),但重啟PyCharm后仍然報錯:
    LookupError: Couldn't find path to unrar library.
    
    然后嘗試在系統變量中新建變量,變量名輸入 UNRAR_LIB_PATH,變量值為 C:\Program Files (x86)\UnrarDLL\x64\UnRAR64.dll(32位系統下的變量值為C:\Program Files (x86)\UnrarDLL\UnRAR.dll)。重啟PyCharm,問題解決。
  2. 基本使用方法
    rarfile庫的使用方法與zipfile十分類似,同樣包含extract(), extractall(), namelist(), infolist(), getinfo(), open(), read(), printdir()等函數,最主要的區別在於,RarFile對象只支持讀取模式,無法寫入文件。
    # mode的值只能為'r'
    class rarfile.RarFile(rarfile, mode='r', charset=None, info_callback=None, crc_check=True, errors='stop')
    
    利用rarfile庫去解壓rar壓縮包,與利用zipfile庫解壓zip格式壓縮包的方法相同,可參考zipfile庫的使用方法。

另外,python-unrar庫的安裝、設置和使用方法與rarfile庫十分類似,但python-unrar庫不支持with語句,如果想使用with語句,可在python-unrar庫安裝目錄下的rarfile.py文件中添加如下語句:

def __enter__(self):
    """Open context."""
    return self
def __exit__(self, typ, value, traceback):
    """Exit context"""
    self.close()
def close(self):
    """Release open resources."""
    pass

tar格式

tar格式是Unix系統下常見的打包文件的格式,搭配不同的壓縮方法可形成不同的壓縮文件格式,如:.tar.gz(.tgz)、.tar.bz2(.tbztb2)、.tar.Z(.taz)、.tar.lzma(.tlz)、.tar.xz(.txz)等。tar格式對應的有python標准庫tarfile,支持的格式包括:tar, tar.gz, tar.bz2, tar.xz, .tar.lzma等。
tarfile庫的基本使用方法:

  1. 創建tarfile對象
    tarfile庫創建對象使用tarfile.open(),而不是使用tarfile.TarFile()。

    tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)
    

    其中,mode可取的值比較多,主要包括'r', 'w', 'a', 'x'四種模式(在zipfile庫的使用中簡單介紹過),以及這四種模式與'gz', 'bz2', 'xz'三種壓縮方法的組合模式,具體取值如下表所示:

    模式 含義
    'r'or'r:*' 自動解壓並打開文件(推薦模式)
    'r:' 只打開文件不解壓
    'r:gz' 采用gzip格式解壓並打開文件
    'r:bz2' 采用bz2格式解壓並打開文件
    'r:xz' 采用lzma格式解壓並打開文件
    'x'or'x:' 僅創建打包文件,不壓縮
    'x:gz' 采用gzip方式壓縮並打包文件
    'x:bz2' 采用bzip2方式壓縮並打包文件
    'x:xz' 采用lzma方式壓縮並打包文件
    'a'or'a:' 打開文件,並以不壓縮的方式追加內容。如果文件不存在,則新建
    'w'or'w:' 以不壓縮的方式寫入
    'w:gz' 以gzip的方式壓縮並寫入
    'w:bz2' 以bzip2的方式壓縮並寫入
    'w:xz' 以lzma的方式壓縮並寫入

    但是,不支持'a'與三種壓縮方法的組合模式('a:gz', 'a:bz2'、'a:xz')

  2. 基本使用方法
    解壓縮至指定的目錄

    with tarfile.open("test.tar.gz") as tar:
        tar.extractall(path='.')
    

    解壓符合某些條件的文件

    # 解壓后綴名為py的文件
    def py_files(members):
        for tarinfo in members:
            if os.path.splitext(tarinfo.name)[1] == ".py":
                yield tarinfo
    with tarfile.open("sample.tar.gz") as tar:
        tar.extractall(members=py_files(tar))
    

    創建不壓縮的打包文件

    with tarfile.open("sample.tar", "w") as tar:
        for name in ["foo", "bar", "quux"]:
            tar.add(name)
    

    創建壓縮的打包文件

    with tarfile.open("sample.tar", "w:gz") as tar:
        for name in ["foo", "bar", "quux"]:
            tar.add(name)
    

    壓縮並打包整個文件夾,較之zipfile庫簡單得多,可使用add()函數進行添加

    tar = tarfile.open('test.tar','w:gz')  
    for root ,dir,files in os.walk(os.getcwd()):  
        for file in files:  
            fullpath = os.path.join(root,file)  
            tar.add(fullpath) 
    

其他壓縮格式

Python原生的數據壓縮打包的標准庫還包括:bz2gzipzliblzma以及建立在zipfile和tarfile庫基礎上的shutil庫,以后有機會再詳細介紹。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM