Python實現解壓rar檔案
零、需求
最近在開發一個填分數的應用,需要用到selenium,那麼自然需要用到瀏覽器,瀏覽器內建到應用中,但是上傳到GitCode的時候被限制了,單個檔案大小隻能是10M以內。所以只能壓縮,分卷,用的時候再解壓就好。zip的分卷解壓要合併後才能解壓,太佔用磁碟資源了,因此用rar。7z之前用過,也比較麻煩,現在想試試rar。
壹、實現
準備工作
安裝rarfile
庫
pip install rarfile
RAR程式
RAR不是開源的,沒有Python實現,本質還是呼叫exe解壓,故需要下載一個WinRAR,安裝WinRAR後我們在WinRAR的安裝目錄中找到UnRAR.exe
,把這個複製到我們專案目錄下即可,這樣其他電腦執行我們的程式碼時不需要另外安裝WinRAR。
程式碼實現
我們需要用到rarfile
這個庫,這個庫的用法跟Python內建的zipfile
用法一樣,所以學習成本幾乎為0,我們要做的就是在使用rarfile
之前把UnRAR.exe
新增到path
環境變數中去。
我們需要把UnRAR.exe
所在目錄傳入這個函式即可,這個函式不會改變系統的設定,隻影響當前程式的環境變數,新增環境變數程式碼如下:
def set_path(path:str):
"""
新增目錄到path環境變數中
:param path: 目錄
:return: None
"""
os_path = os.environ.get('path')
if path in os_path:
return
else:
if os.path.exists(path):
os.environ['path'] = f'{os_path};{path};'
else:
raise ValueError('環境變數路徑不存在')
之後是解壓程式碼的實現,這個跟zipfile
一樣用的:
def unrar_file(rar_file, target_path=None, password=None, progress_fun=None):
"""
解壓rar檔案
:param rar_file: 檔案路徑
:param target_path: 解壓目標路徑
:param password: 密碼
:param progress_fun: 進度函式,會傳遞一個 0-1的進度浮點
:return: 成功 True
"""
# 設定環境變數
set_path(
get_relative_path('chrome')
)
# 設定密碼
if not (password is None):
password = password.encode('utf-8')
logger.debug('解壓rar檔案:' + str(rar_file))
# 開啟rar檔案
rf = rarfile.RarFile(rar_file)
try:
file_list = rf.infolist()
# 統計總大小
all_size = 0
for i in file_list:
all_size += i.file_size
# 解壓
unrar_size = 0
for file in file_list:
rf.extract(file, path=target_path, pwd=password)
unrar_size += file.file_size
# 呼叫顯示進度的函式
if progress_fun:
progress_fun(unrar_size / all_size)
except Exception as e:
raise e
finally:
rf.close()
return True
程式碼中get_relative_path
函式是透過相對路徑獲取絕對路徑的函式,這個與本文無關就不貼出了,返回就是一個絕對路徑。程式碼中logger
是日誌物件,相當於就是列印函式,可以改成print
輸出。程式碼中progress_fun
函式是列印進度的函式,接受一個浮點數,代表進度,這個大家可以自己實現一下,也可以直接刪除。
貳、參考文件
- rarfile API documentation