1. python實作zip分卷壓縮
WinHex 開始16進制一個一個檔案對比 WinRar 建立的分卷壓縮和單個 zip 檔案的差異。
如果想把單個大檔案
test.zip
-> 分卷檔案
test.z01
、
test.z02
、
test.zip
首先,在建立的第一個分卷檔案
test.z01
的前面加上
\x50\x4b\x07\x08
這個是分卷壓縮的檔案頭(header),占4個位元組。其實單個壓縮檔案本身 header 就有這個了,而分卷壓縮的需要兩個emmm。之後便是從單個大壓縮檔案檔案
test.zip
中讀取 "一個分卷大小 -4 個位元組"的資料,寫入
test.z01
中,如何接着讀取一個分卷大小的資料,寫入
test.z02
,以此類推,最後一個分卷檔案名也是
test.zip
1.1 代碼如下:
import os
import zipfile
def zip_by_volume(file_path, block_size):
"""zip檔案分卷壓縮"""
file_size = os.path.getsize(file_path) # 檔案位元組數
path, file_name = os.path.split(file_path) # 除去檔案名以外的path,檔案名
suffix = file_name.split('.')[-1] # 檔案字尾名
# 添加到臨時壓縮檔案
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
# 建立分卷壓縮檔案的儲存路徑
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位元組)
f.write(fp.read(block_size - 4))
else:
f.write(fp.read(block_size))
fp.close()
os.remove(zip_file) # 删除臨時的 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) # 輸出分卷壓縮檔案的路徑