python分包壓縮的方法-創(chuàng)新互聯(lián)

創(chuàng)新互聯(lián)www.cdcxhl.cn八線(xiàn)動(dòng)態(tài)BGP香港云服務(wù)器提供商,新人活動(dòng)買(mǎi)多久送多久,劃算不套路!

從事服務(wù)器托管,服務(wù)器租用,云主機(jī),網(wǎng)絡(luò)空間,空間域名,CDN,網(wǎng)絡(luò)代維等服務(wù)。

不懂python分包壓縮的方法?其實(shí)想解決這個(gè)問(wèn)題也不難,下面讓小編帶著大家一起學(xué)習(xí)怎么去解決,希望大家閱讀完這篇文章后大所收獲。

利用 Python 壓縮 ZIP 文件,我們第一反應(yīng)是使用 zipfile 庫(kù),然而,它的官方文檔中卻明確標(biāo)注“此模塊目前不能處理分卷 ZIP 文件”(⊙﹏⊙)

1、折騰經(jīng)過(guò):

翻遍了Google、CSDN、Stackoverflow等平臺(tái)均未找到解決方案,最靠譜的是調(diào)用外部解壓程序?qū)崿F(xiàn)分卷壓縮的功能。但是,如何不依靠外部程序?qū)崿F(xiàn)這個(gè)功能呢??

于是乎,只能自己慢慢造輪子??粗?ZIP 格式開(kāi)發(fā)商留下的文檔 ZIP File Format Specification,頭疼啊(;′д`)。于是我拿著 WinHex 開(kāi)始16進(jìn)制一個(gè)一個(gè)文件對(duì)比 WinRar 創(chuàng)建的分卷壓縮和單個(gè) zip 文件的差異。最后還真的整出來(lái)了( ̄▽?zhuān)?"

python分包壓縮的方法

如果想把單個(gè)大文件 test.zip -> 分卷文件 test.z01、test.z02、test.zip

首先,在創(chuàng)建的第一個(gè)分卷文件 test.z01的前面加上 \x50\x4b\x07\x08 這個(gè)是分卷壓縮的文件頭(header),占4個(gè)字節(jié)。其實(shí)單個(gè)壓縮文件本身 header 就有這個(gè)了,而分卷壓縮的需要兩個(gè)emmm。之后便是從單個(gè)大壓縮文件文件test.zip中讀取 "一個(gè)分卷大小 -4 個(gè)字節(jié)"的數(shù)據(jù),寫(xiě)入test.z01中,如何接著讀取一個(gè)分卷大小的數(shù)據(jù),寫(xiě)入test.z02,以此類(lèi)推,最后一個(gè)分卷文件名也是test.zip。

2、Python3的代碼實(shí)現(xiàn):

import os
import zipfile
def zip_by_volume(file_path, block_size):
    """zip文件分卷壓縮"""
    file_size = os.path.getsize(file_path)  # 文件字節(jié)數(shù)
    path, file_name = os.path.split(file_path)  # 除去文件名以外的path,文件名
    suffix = file_name.split('.')[-1]  # 文件后綴名
    # 添加到臨時(shí)壓縮文件
    zip_file = file_path + '.zip'
    with zipfile.ZipFile(zip_file, 'w') as zf:
        zf.write(file_path, arcname=file_name)
    # 小于分卷尺寸則直接返回壓縮文件路徑
    if file_size <= block_size:
        return zip_file
    else:
        fp = open(zip_file, 'rb')
        count = file_size // block_size + 1
        # 創(chuàng)建分卷壓縮文件的保存路徑
        save_dir = path + os.sep + file_name + '_split'
        if os.path.exists(save_dir):
            from shutil import rmtree
            rmtree(save_dir)
        os.mkdir(save_dir)
        # 拆分壓縮包為分卷文件
        for i in range(1, count + 1):
            _suffix = 'z{:0>2}'.format(i) if i != count else 'zip'
            name = save_dir + os.sep + file_name.replace(str(suffix), _suffix)
            f = open(name, 'wb+')
            if i == 1:
                f.write(b'\x50\x4b\x07\x08')  # 添加分卷壓縮header(4字節(jié))
                f.write(fp.read(block_size - 4))
            else:
                f.write(fp.read(block_size))
        fp.close()
        os.remove(zip_file)     # 刪除臨時(shí)的 zip 文件   
        return save_dir
if __name__ == '__main__':
    file = r"D:\Downloads\1.mp4"        # 原始文件
    volume_size = 1024 * 1024 * 100  # 分卷大小 100MB
    path = zip_by_volume(file, volume_size)
    print(path)     # 輸出分卷壓縮文件的路徑

3、缺點(diǎn):

該方法創(chuàng)建分卷壓縮的時(shí)候,需要先在磁盤(pán)創(chuàng)建一個(gè)臨時(shí)壓縮包,然后將其拆分,實(shí)際上會(huì)對(duì)磁盤(pán)寫(xiě)入兩次,這就浪費(fèi)了時(shí)間。

當(dāng)然,我嘗試使用 ByteIO 進(jìn)行字節(jié)流的壓縮,但是這種方式需要先把文件讀入內(nèi)存,對(duì)于超級(jí)大的文件,這是不現(xiàn)實(shí)的,分分鐘內(nèi)存爆炸。

然后,我嘗試使用 io.pipe 的管道來(lái)處理,而 zipfile 壓縮需要提供一個(gè) file 或 file-like 對(duì)象,這個(gè)對(duì)象必須實(shí)現(xiàn) seek() 和 tell() 方法來(lái)回去寫(xiě)入文件頭信息,然而管道流沒(méi)辦法seek回去修改數(shù)據(jù)。這里,參考了Python zipfile + os.pipe()探索記,屏蔽了 seek() 和 tell() 函數(shù)。但是,后面我分卷時(shí)需要指定讀取的字節(jié)數(shù),這就需要這兩個(gè)函數(shù)。。。我大概知道為什么 zipfile 庫(kù)不支持創(chuàng)建分卷文件了〒▽〒

這個(gè)庫(kù)的作者也沒(méi)少掉頭發(fā)。?!,F(xiàn)在就將就一下,這樣用著吧。。。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享python分包壓縮的方法內(nèi)容對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,遇到問(wèn)題就找創(chuàng)新互聯(lián),詳細(xì)的解決方法等著你來(lái)學(xué)習(xí)!

本文標(biāo)題:python分包壓縮的方法-創(chuàng)新互聯(lián)
當(dāng)前地址:http://muchs.cn/article26/dpshcg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站搜索引擎優(yōu)化、建站公司企業(yè)建站、定制開(kāi)發(fā)手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

營(yíng)銷(xiāo)型網(wǎng)站建設(shè)