python處理常見格式壓縮包文件的全指南
1.7z壓縮包
安裝py7zr庫
pip install py7zr
解壓.7z文件
以下示例代碼將一次性把"F:/Ticks/test.7z"壓縮文件里面的所有文件一一按照原文件層次結(jié)構遞歸解壓到"F:/Ticks/test"目錄下。注意,如果xxx.7z里面包含有壓縮文件,將不會解壓。
import py7zr
def un_7z(file_7z_path):
save_dir = file_7z_path[:file_7z_path.rfind(".7z")]
archive = py7zr.SevenZipFile(file_7z_path, mode='r')
archive.extractall(path=save_dir)
archive.close()
if __name__ == "__main__":
filepath = "F:/Ticks/test.7z"
un_7z(filepath)
源文件夾目錄結(jié)構

解壓后是保持一致的

py7zr (v0.6及更高版本) 也提供了上下文管理,所以可以使用 with 代碼塊:
import py7zr
with py7zr.SevenZipFile('sample.7z', mode='r') as z:
z.extractall()
py7zr 還支持提取單個或通過 extract(targets=[‘file path’]) 選特定的多個文件進行解壓。注意:如果只指定文件而不指定父目錄,將會提取失敗。
import py7zr
import re
filter_pattern = re.compile(r'<your/target/file_and_directories/regex/expression>')
with SevenZipFile('archive.7z', 'r') as archive:
allfiles = archive.getnames()
selective_files = [f for f in allfiles if filter_pattern.match(f)]
archive.extract(targets=selective_files)
py7zr(v0.6及更高版本)支持提取受密碼保護的歸檔文件。
import py7zr
with py7zr.SevenZipFile('encrypted.7z', mode='r', password='secret') as z:
z.extractall()
壓縮為.7z文件
下面是一段如何生成歸檔文件的示例代碼
import py7zr
with py7zr.SevenZipFile('target.7z', 'w') as archive:
archive.writeall('/path/to/base_dir', 'base')
with py7zr.SevenZipFile('target.7z', 'w') as z:
z.writeall('./base_dir')
要創(chuàng)建加密存檔,請傳遞密碼
import py7zr
with py7zr.SevenZipFile('target.7z', 'w', password='secret') as archive:
archive.writeall('/path/to/base_dir', 'base')
要使用zstandard等算法創(chuàng)建存檔,可以使用自定義過濾器調(diào)用。
import py7zr
my_filters = [{"id": py7zr.FILTER_ZSTD}]
another_filters = [{"id": py7zr.FILTER_ARM}, {"id": py7zr.FILTER_LZMA2, "preset": 7}]
with py7zr.SevenZipFile('target.7z', 'w', filters=my_filter) as archive:
archive.writeall('/path/to/base_dir', 'base')
7z壓縮包分卷的解壓縮
①分卷長什么樣
正常情況下是把文件夾filename壓縮為filename.7z壓縮包,但7z也提供了用分卷的形式,比如11個分卷
filename.7z.001,filename.7z.002,filename.7z.003,filename.7z.004,.......,filename.7z.011
7z.001這類文件是7z格式文件簡單分割出的
②如何手動解壓分卷形式的壓縮包
要將全部分卷放在同一個目錄下,然后解壓filename.7z.001即可,如果filename.7z.001所在目錄下缺少部分分卷,則會無法解壓或者解壓失敗
③如何將分卷壓縮包合并為7z壓縮包文件
linux環(huán)境下
進入分卷所在文件夾,使用指令
cat {文件名1} {文件名2} {文件名n} > {生成文件名}
下以文件名 shapeNetP2M.7z為例,執(zhí)行如下命令:
cat ShapeNetP2M.7z-001.001 ShapeNetP2M.7z-002.002 ShapeNetP2M.7z-003.003 >ShapeNetP2M.7z
[root@localhost 7ztest]# ls
BondTick.7z.001 BondTick.7z.002 BondTick.7z.003 BondTick.7z.004 BondTick.7z.005 BondTick.7z.006 BondTick.7z.007 BondTick.7z.008 BondTick.7z.009 BondTick.7z.010 BondTick.7z.011
[root@localhost 7ztest]# cat * > BondTick.7z
windows環(huán)境下
1、在G:\Downloads\Test目錄中有一批Test.7z.00x分卷壓縮文件(后綴一般為001-00x)。
2、首先使用快捷鍵“Win+R”彈出運行命令框,輸入:cmd,打開命令行窗口。
3、輸入:cd /d G:\Downloads\Test,進入7z分卷文件目錄中。
4、然后輸入:copy /b test.7z.* test.7z。
5、成功后就會在當前目錄看到一個test.7z文件(7z后綴)
2.tar和gz壓縮包
安裝相關包
Python自帶的tarfile模塊可以方便讀取tar歸檔文件,牛b的是可以處理使用gzip和bz2壓縮歸檔文件tar.gz和tar.bz2。
tarfile包常用函數(shù)
①tarfile.open
創(chuàng)建tar文件對象
tarfile.open(name=None,mode='r',fileobj=None,bufsize=10240,**kwargs)
mode的值有:
- 'r' or 'r:*' Open for reading with transparent compression (recommended).
- 'r:' Open for reading exclusively without compression.
- 'r:gz' Open for reading with gzip compression.
- 'r:bz2' Open for reading with bzip2 compression.
- 'a' or 'a:' Open for appending with no compression. The file is created if it does not exist.
- 'w' or 'w:' Open for uncompressed writing.
- 'w:gz' Open for gzip compressed writing.
- 'w:bz2' Open for bzip2 compressed writing.
②tar.close()
關閉文件對象
③tar.add(filepath)
將文件filepath添加到壓縮包文件中
④tar.getnames()
獲取壓縮包里的全部目錄和文件路徑,返回列表,比如壓縮包是linux環(huán)境下的某個壓縮包,壓縮時某個文件路徑是"/home/tick/test/20230510/601669_snap.csv",則返回列表里的某個元素就是"/home/pjzy003/test/20230510/601669_snap.csv"
⑤tar.extract(file_name, target_dir)
將壓縮包文件中的文件file_name解壓到target_dir中,最終解壓后的文件路徑或者目錄路徑為target_dir+file_name
- 比如target_dir="D:\xxx\yyy",file_name="test\20230510",則新生成的文件夾為"D:\xxx\yyy\test\20230510"
- 比如target_dir="D:/xxx/yyy",file_name="/home/tick/test/20230510/601669_snap.csv",則新生成的文件為"D:/xxx/yyy/home/tick/test/20230510/601669_snap.csv"
注意:tar.extract函數(shù)的第一個參數(shù)必須傳入tar.getnames()這個函數(shù)返回的列表里的元素
壓縮為tar.gz文件
import os
import tarfile
if __name__ == "__main__":
dir_path = r"D:\PythonTest\20220510"
tar_gz_path = f"{dir_path}.tar.gz"
# 1.創(chuàng)建tar文件對象
tar = tarfile.open(tar_gz_path, "w:gz")
# 2.將子目錄和文件添加到tar對象中
for root, dirs, files in os.walk(dir_path):
# 2.1先將目錄添加到壓縮包中
tar.add(root)
# 2.2再將目錄下的文件添加到壓縮包中
for file in files:
fullpath = os.path.join(root, file)
tar.add(fullpath)
# 3.關閉tar對象
tar.close()
解壓tar.gz文件
用法示例
import os
import tarfile
if __name__ == "__main__":
tar_gz_path = r"D:\PythonTest\test\20220510.tar.gz"
# 以下代碼將tar.gz文件解壓到了同級目錄下
# 比如D:\PythonTest\test\20220510.tar.gz
# 解壓后產(chǎn)生D:\PythonTest\test\20220510
# 處理路徑信息
tar_gz_path = tar_gz_path.replace("\\", "/")
tar_gz_dir = tar_gz_path[:tar_gz_path.rfind("/")]
tar_gz_name = tar_gz_path[tar_gz_path.rfind("/")+1:]
dir_name = tar_gz_name[:-7]
# 創(chuàng)建tar文件對象
tar = tarfile.open(tar_gz_path, "r:gz")
# 獲取壓縮包下的所有子目錄和文件路徑
file_names = tar.getnames()
print(file_names)
# 解壓
for file_name in file_names:
print("=============")
print("file_name:", file_name)
pre_name = file_name[:file_name.rfind(dir_name)-1]
print("pre_name:", pre_name)
save_dir = tar_gz_dir[:tar_gz_dir.rfind(pre_name)]
print("save_dir:", save_dir)
tar.extract(file_name, save_dir)
# 關閉tar對象
tar.close()
將其封裝為函數(shù)。與示例相比,這里的函數(shù)處理了文件路徑的細節(jié)問題,比如壓縮的路徑"D:\data\20230510.tar.gz",壓縮包里面的文件路徑是"/home/tick/test/20230510/601669_snap.csv",則解壓后的文件路徑是"D:/data/20230510/home/tick/test/20230510/601669_snap.csv",但是我們想要的是"D:/data/20230510/601669_snap.csv"這種效果,因此需要處理,具體見下方代碼。
import os
import shutil
import tarfile
def un_tar_gz(gz_file_path):
"""
:param gz_file_path: tar.gz文件路徑,比如D:/PythonTest/test/20220510.tar.gz
:return: None
函數(shù)作用:
將tar.gz文件解壓到了同級目錄下
比如D:/PythonTest/test/20220510.tar.gz解壓后產(chǎn)生D:/PythonTest/test/20220510
"""
# 判斷傳輸?shù)奈募愋褪欠裾_
if gz_file_path[-7:] != ".tar.gz":
print(f"{gz_file_path} not tar.gz type")
return None
# 若文件不存在
if not os.path.exists(gz_file_path):
print(f"{gz_file_path} not exists")
return None
# 處理路徑信息
tar_gz_path = gz_file_path.replace("\\", "/")
tar_gz_dir = tar_gz_path[:tar_gz_path.rfind("/")]
tar_gz_name = tar_gz_path[tar_gz_path.rfind("/") + 1:]
tar_gz_name_pre = tar_gz_name[:-7]
save_dir = tar_gz_dir + "/" + tar_gz_name_pre
save_dir_temp = save_dir + "_temp"
# 創(chuàng)建tar文件對象
tar = tarfile.open(tar_gz_path, "r:gz")
# 獲取壓縮包下的所有子目錄和文件路徑
file_names = tar.getnames()
# print(file_names)
# 解壓,解壓后的文件名為 save_dir + file_name
for file_name in file_names:
tar.extract(file_name, save_dir_temp)
# 關閉tar對象
tar.close()
# 創(chuàng)建同級目錄
if not os.path.exists(save_dir):
os.mkdir(save_dir)
# 將解壓后的文件移動到同級目錄下
for file_name in file_names:
temp_file_path = save_dir_temp+"/"+file_name
start_index = file_name.rfind(tar_gz_name_pre) + len(tar_gz_name_pre)
final_file_path = save_dir+"/"+file_name[start_index:]
if not os.path.exists(final_file_path):
if os.path.isdir(temp_file_path):
os.mkdir(final_file_path)
else:
shutil.move(temp_file_path, final_file_path)
# 刪除臨時目錄
if os.path.exists(save_dir_temp):
shutil.rmtree(save_dir_temp)
if __name__ == "__main__":
gz_path = r"D:\PythonTest\test\20220510.tar.gz"
un_tar_gz(gz_path)
將tar.gz解壓tar文件
import gzip
def ungz(filename):
filename = filename[:-3]
# gz文件的單文件解壓就是去掉 filename 后面的 .gz
gz_file = gzip.GzipFile(filename)
with open(filename, "w+") as file:
file.write(gz_file.read())
return filename # 這個gzip的函數(shù)需要返回值以進一步配合untar函數(shù)
解壓tar文件
import tarfile
def untar(filename):
tar = tarfile.open(filename)
names = tar.getnames()
# tar本身是將文件打包,解除打包會產(chǎn)生很多文件,因此需要建立文件夾存放
if not os.path.isdir(filename + "_dir"):
os.mkdir(filename + "_dir")
for name in names:
tar.extract(name, filename + "_dir/")
tar.close()
3.zip類壓縮包
使用zipfile模塊
import zipfile
def unzip(filename):
zip_file = zipfile.ZipFile(filename)
# 類似tar解除打包,建立文件夾存放解壓的多個文件
if not os.path.isdir(filename + "_dir"):
os.mkdir(filename + "_dir")
for names in zip_file.namelist():
zip_file.extract(names, filename + "_dir/")
zip_file.close()
4.處理.rar文件
使用rarfile包
import rarfile
import os
def unrar(filename):
rar = rarfile.RarFile(filename)
if not os.path.isdir(filename + "_dir"):
os.mkdir(filename + "_dir")
os.chdir(filename + "_dir") # 改變當前工作路徑
rar.extractall() # 將全部文件解壓到當前工作路徑
rar.close()以上就是python處理常見格式壓縮包文件的全指南的詳細內(nèi)容,更多關于python處理壓縮包文件的資料請關注腳本之家其它相關文章!
相關文章
Django把SQLite數(shù)據(jù)庫轉(zhuǎn)換為Mysql數(shù)據(jù)庫的過程
之前我們默認使用的是SQLite數(shù)據(jù)庫,我們開發(fā)完成之后,里面有許多數(shù)據(jù),如果我們想轉(zhuǎn)換成Mysql數(shù)據(jù)庫,那我們先得把舊數(shù)據(jù)從SQLite導出,然后再導入到新的Mysql數(shù)據(jù)庫里去,這篇文章主要介紹了Django如何把SQLite數(shù)據(jù)庫轉(zhuǎn)換為Mysql數(shù)據(jù)庫,需要的朋友可以參考下2023-05-05
pytorch使用nn.Moudle實現(xiàn)邏輯回歸
這篇文章主要為大家詳細介紹了pytorch使用nn.Moudle實現(xiàn)邏輯回歸,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-07-07
django處理select下拉表單實例(從model到前端到post到form)
這篇文章主要介紹了django處理select下拉表單實例(從model到前端到post到form),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Python matplotlib畫圖實例之繪制擁有彩條的圖表
這篇文章主要介紹了Python matplotlib畫圖實例之繪制擁有彩條的圖表,具有一定借鑒價值,需要的朋友可以參考下2017-12-12
Python連接數(shù)據(jù)庫學習之DB-API詳解
在沒有 Python DB-API 之前,各數(shù)據(jù)庫之間的應用接口非?;靵y,實現(xiàn)各不相同。如果項目需要更換數(shù)據(jù)庫時,則需要做大量的修改,非常不便。Python DB-API 的出現(xiàn)就是為了解決這樣的問題。本文主要介紹了Python連接數(shù)據(jù)庫之DB-API的相關資料,需要的朋友可以參考。2017-02-02
Python中threading庫實現(xiàn)線程鎖與釋放鎖
threading用于提供線程相關的操作,為了保證安全的訪問一個資源對象,我們需要創(chuàng)建鎖。那么Python線程鎖與釋放鎖如何實現(xiàn),感興趣的小伙伴們可以參考一下2021-05-05

