溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么在 Python項(xiàng)目中利用 7zip 對文件進(jìn)行備份

發(fā)布時間:2020-12-11 13:48:52 來源:億速云 閱讀:701 作者:Leah 欄目:開發(fā)技術(shù)

怎么在 Python項(xiàng)目中利用 7zip 對文件進(jìn)行備份?針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

下面三種方法可以在python中正確運(yùn)行7z命令:

# 方法1: 拷貝 7z.exe 和7z.dll 到當(dāng)前python文件所在的目錄下。 否則,不認(rèn)識7z 命令。

zip_command = '7z a -tzip {0} {1} -r'.format(target, ' '.join(source))

# 方法2: os.system() 里面執(zhí)行的是同目錄下的exe, 使用如下os.chdir() 命令切換 path。

os.chdir('D:\\Program Files (x86)\\7-Zip')
print('切換當(dāng)前路徑為:', os.getcwd())
zip_command = '7z a -tzip {0} {1} -r'.format(target, ' '.join(source))

# 方法3:在cmd 命令中寫入7z.exe所在的目錄

zip_command = '"D:\\Program Files (x86)\\7-Zip\\7z.exe" a -tzip {0} {1} '.format(target, ' '.join(source))

import os
import time
 
# 1. 需要備份的文件與目錄將被指定在一個列表中。
# 例如在 Windows 下:source = ['"C:\\My Documents"', 'C:\\Code']
# 又例如在 Mac OS X 與 Linux 下:source = ['/Users/swa/notes']
source = ['D:\\test\\fold\\']
# 在這里要注意到我們必須在字符串中使用雙引號用以括起其中包含空格的名稱。
 
# 2. 備份文件必須存儲在一個主備份目錄中
# 例如在 Windows 下:target_dir = 'E:\\Backup'
# 又例如在 Mac OS X 和 Linux 下:target_dir = '/Users/swa/backup'
target_dir = 'D:\\test\\Backup'
# 要記得將這里的目錄地址修改至你將使用的路徑
 
# 3. 備份文件將打包壓縮成 zip 文件。
# 4. zip 壓縮文件的文件名由當(dāng)前日期與時間構(gòu)成。
# os.sep 變量的使用方式——它將根據(jù)你的操作系統(tǒng)給出相應(yīng)的分隔符,在# GNU/Linux 與 Unix 中它會是 '/' ,在 Windows 中它會是 '\\' ,在 Mac OS 中它會是 ':'
target = target_dir + os.sep + time.strftime('%Y%m%d%H%M%S') + '.zip'
 
# 如果目標(biāo)目錄還不存在,則進(jìn)行創(chuàng)建
if not os.path.exists(target_dir):
 os.mkdir(target_dir)
 
# 5. 我們使用 zip 命令將文件打包成 zip 格式
# 方法1: 拷貝 7z.exe 和7z.dll 到當(dāng)前python文件所在的目錄下。 否則,不認(rèn)識7z 命令。
# zip_command = '7z a -tzip {0} {1} -r'.format(target, ' '.join(source))
 
# 方法2: os.system() 里面執(zhí)行的是同目錄下的exe, 使用如下os.chdir() 命令切換 path。
# os.chdir('D:\\Program Files (x86)\\7-Zip')
# print('切換當(dāng)前路徑為:', os.getcwd())
# zip_command = '7z a -tzip {0} {1} -r'.format(target, ' '.join(source))
 
# 方法3:在cmd 命令中寫入7z.exe所在的目錄
# -mcu 強(qiáng)制使用utf-8 編碼文件名
zip_command = '"D:\\Program Files (x86)\\7-Zip\\7z.exe" a -tzip -mcu {0} {1} '.format(target, ' '.join(source))
# 運(yùn)行備份
print('\nZip command is:')
print(zip_command)
print('Running:') 
 
if os.system(zip_command) == 0:
 print('Successful backup to', target)
else:
 print('Backup FAILED')
 
# 查看壓縮文件內(nèi)容
check_command = '"D:\\Program Files (x86)\\7-Zip\\7z.exe" l {0}'.format(target)
 
print('\nCheck zipfile command is:')
print(check_command)
print('Running:')
 
# 使用 os.system(check_command) 中文返回有亂碼,所以使用 os.popen
# if os.system(check_command) == 0:
# print('Please check the file list in:', target)
# else:
# print('Check info FAILED')
print('Please check the file list in:', target)
p = os.popen(check_command)
print(p.read())
p.close()
 
 
# 解壓縮到目錄
extr_command = '"D:\\Program Files (x86)\\7-Zip\\7z.exe" x {0} -oD:\\test\\extract\\ -y'.format(target)
 
print('\nExtract command is:')
print(extr_command)
print('Running:')
 
if os.system(extr_command) == 0:
 print('Successful extract to', 'D:\\test\\extract')
else:
 print('Extract FAILED')

注意:

在壓縮的時候,不要使用 -r,遞歸會把folder同級的其它目錄下的文件一起壓縮;

在解壓的時候,使用-y,如果當(dāng)前目錄下已存在被解壓的目錄和文件,替換目標(biāo)文件。

zip_command = '"D:\\Program Files (x86)\\7-Zip\\7z.exe" a -tzip {0} {1} -r'.format(target, ' '.join(source))

extr_command = '"D:\\Program Files (x86)\\7-Zip\\7z.exe" x {0} -oD:\\test\\extract\\ -y'.format(target)

補(bǔ)充知識:誰說Python的shutil不支持7z解壓縮,我來教你擴(kuò)展它的功能!

python的內(nèi)置模塊

在Python的標(biāo)準(zhǔn)庫中,有哪些你常用并且覺得犀利無比的模塊?不要說time、datetime、os、sys。這些模塊常用是常用,但是逼格不夠高啊。舉個例子,如果你經(jīng)常在LeetCode上刷題,你會發(fā)現(xiàn)有時Java、C需要幾十行的算法題,如果Python使用了collections、itertools,可能三四行代碼就結(jié)束了。

shutil的便利

日常的編碼中,常會涉及到對文件、目錄等的操作場景,如果我們使用os,可能需要對文件、文件夾,非空等進(jìn)行逐個判斷。舉個例子: 我們現(xiàn)在要刪除一個目錄,目錄中包含有文件與文件夾,如果使用os模塊,沒有現(xiàn)成可以使用的函數(shù),需要我們進(jìn)行判斷與分類執(zhí)行。

import os
# path是文件的路徑,如果這個路徑是一個文件夾,
# 則會拋出OSError的錯誤,這時需用用rmdir()來刪除
os.remove(path)
# path是文件夾路徑,注意文件夾需空的才能被刪除
os.rmdir(path)

多數(shù)初學(xué)者遇到刪除文件夾,想到的操作就是,創(chuàng)建兩個列表,然后用os.walk遍歷目錄,將文件與文件夾分別存入初始化的兩個列表中,然后先統(tǒng)一刪除文件,最后刪除文件夾。如果有上面這樣操作的同學(xué),請面壁三分鐘。明顯沒有好好學(xué)習(xí)os.walk函數(shù)。

os.walk(top[, topdown=True[, οnerrοr=None[, followlinks=False]]]) top -- 是你所要遍歷的目錄的地址, 返回的是一個三元組(root,dirs,files)。

root 所指的是當(dāng)前正在遍歷的這個文件夾的本身的地址

dirs 是一個 list ,內(nèi)容是該文件夾中所有的目錄的名字(不包括子目錄)

files 同樣是 list , 內(nèi)容是該文件夾中所有的文件(不包括子目錄)

topdown --可選,為 True,則優(yōu)先遍歷 top 目錄,否則優(yōu)先遍歷 top 的子目錄(默認(rèn)為開啟)。如果 topdown 參數(shù)為 True,walk 會遍歷top文件夾,與top 文件夾中每一個子目錄。

onerror -- 可選,需要一個 callable 對象,當(dāng) walk 需要異常時,會調(diào)用。

followlinks -- 可選,如果為 True,則會遍歷目錄下的快捷方式(linux 下是軟連接 symbolic link )實(shí)際所指的目錄(默認(rèn)關(guān)閉),如果為 False,則優(yōu)先遍歷 top 的子目錄。

只需要將topdown設(shè)置為False,這樣在遍歷目錄時,就會從根節(jié)點(diǎn)進(jìn)行遍歷,然后我們逐個刪除就ok了,哪里需要那么麻煩!代碼如下:

import os 
for root, dirs, files in os.walk('D:\\software_temp', topdown=False):
 for name in files:
 os.remove(os.path.join(root, name))
 for name in dirs:
 os.rmdir(os.path.join(root, name))

說這么多,無外乎為了引出最簡便的方式 : shutil模塊

如果換做shutil模塊登場,那么執(zhí)行刪除目錄的操作,只需要0.1秒的時間:

import shutil

shutil.rmtree('D:\\software_temp')

就這樣,完事兒了...

文件解壓縮

日常工作中,我們經(jīng)常會使用python進(jìn)行文件的解壓縮處理。python自帶的解壓縮模塊有zipfile, gzip, tarfile,如果我們需要解壓rar文件則需要單獨(dú)下載rarfile模塊,針對每一種壓縮文件,我們都需要針對文件類型進(jìn)行對應(yīng)模塊的使用,是不是很繁瑣?如果我們使用shutil呢?讓我們先來看看shutil支持的解壓類型:

import pprint
import shutil
pprint.pprint(shutil.get_unpack_formats())
 
output:
[('bztar', ['.tar.bz2', '.tbz2'], "bzip2'ed tar-file"),
 ('gztar', ['.tar.gz', '.tgz'], "gzip'ed tar-file"),
 ('tar', ['.tar'], 'uncompressed tar file'),
 ('xztar', ['.tar.xz', '.txz'], "xz'ed tar-file"),
 ('zip', ['.zip'], 'ZIP file')]

shutil已經(jīng)包含了我們上面提到的所有文件。

.7z文件是什么鬼?

眾所周知,zip的壓縮率相比rar是比較低的,但是商業(yè)軟件下載中,你很少會見到.rar的文件,why?因?yàn)閷@?..

RAR是一種專利文件格式,用于數(shù)據(jù)壓縮與歸檔打包,開發(fā)者為尤金·羅謝爾(俄語:Евгений Лазаревич Рошал,拉丁轉(zhuǎn)寫:Yevgeny Lazarevich Roshal),RAR的全名是“Roshal ARchive”,即“羅謝爾的歸檔”之意。首個公開版本RAR 1.3發(fā)布于1993年。

所以,有很多產(chǎn)品在軟件發(fā)布時,開始使用一種壓縮率更高的.7z文件,這又是為什么?來讓我們訪問一下7-zip的官網(wǎng):7-zip官方主頁:https://sparanoid.com/lab/7z/在其中有一個許可協(xié)議是這樣寫的

許可協(xié)議:

7-Zip 是一款 開源 軟件。大多數(shù)源代碼都基于 GNU LGPL 許可協(xié)議下發(fā)布。AES 代碼基于 BSD 許可下發(fā)布。unRAR 代碼基于兩種許可:GNU LGPL 和 unRAR 限制許可。更多下許可信息請查看:7-Zip 許可。您可以在任何一臺計算機(jī)上使用 7-Zip ,包括用在商業(yè)用途的計算機(jī),不對 7-Zip 進(jìn)行捐贈或支付并不影響您的使用。

shutil擴(kuò)展7z

說了這么多7z文件的好處,可我們看到shutil并不能解壓該類型的文件啊。我們能否讓shutil支持.7z文件,達(dá)到無腦解壓縮呢?此時,你需要py7zr模塊。養(yǎng)成好習(xí)慣,遇到模塊先找GitHub:https://github.com/miurahr/py7zr

1. 模塊下載

pip install py7zr

2. 基本使用

當(dāng)我們安裝好py7zr后,它可以在cmd下直接運(yùn)行該命令

List archive contents
$ py7zr l test.7z
Extract archive
$ py7zr x test.7z
Extract archive with password
$ py7zr x -P test.7z
 password?: ****
Create and compress to archive
$ py7zr c target.7z test_dir
Create multi-volume archive
$ py7zr c -v 500k target.7z test_dir
Test archive
$ py7zr t test.7z
Show information
$ py7zr i
Show version
$ py7zr --version

單獨(dú)使用模塊

import py7zr
 
archive = py7zr.SevenZipFile('sample.7z', mode='r')
archive.extractall(path="/tmp")
archive.close()
 
with py7zr.SevenZipFile('target.7z', 'w') as z:
 z.writeall('./base_dir')

3. shutil集成

之所以推薦py7zr給大家,不僅因?yàn)樗暮唵魏糜?,更是由于他可以輕松集成于shutil,來看看它的使用方式吧:

from py7zr import pack_7zarchvie, unpack_7zarchive
import shutil
 
# register file format at first.
shutil.register_archive_format('7zip',
    pack_7zarchive,
    description='7zip archive')
 
shutil.register_unpack_format('7zip',
    ['.7z'],
    unpack_7zarchive,
    description='7zip archive')
 
# extraction
shutil.unpack_archive('test.7z', '/tmp')
 
# compression
shutil.make_archive('target', '7zip', 'src')
 
pprint.pprint(shutil.get_unpack_formats())
 
# output:
[('7zip', ['.7z'], '7zip archive'),
 ('bztar', ['.tar.bz2', '.tbz2'], "bzip2'ed tar-file"),
 ('gztar', ['.tar.gz', '.tgz'], "gzip'ed tar-file"),
 ('tar', ['.tar'], 'uncompressed tar file'),
 ('xztar', ['.tar.xz', '.txz'], "xz'ed tar-file"),
 ('zip', ['.zip'], 'ZIP file')]

通過注冊我們看到,shutil已經(jīng)支持7z文件的解壓了

關(guān)于怎么在 Python項(xiàng)目中利用 7zip 對文件進(jìn)行備份問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI