VIRTOK
Кроме того нужно организовать деление архивов на части используя
zipfile
zipfile ровно как и ZIP формат не предусматривает разбивку на части. Поэтому вам придеться пилить свой велосипед.
Я вижу несколько путей:
1. Создаем архив с именем name001.zip берем файлы и пихаем туда по одному, смотрим если размер архива превышает “размер тома”, закрываем его, создаем архив с именем name002.zip и и так по кругу
Полюсы:
- получаем архивы открывающиеся любым архиватором
Минусы:
- неравные размеры томов,
- всеже у нас не один архив а куча, с которыми может быть неудобно работать.
- слишком большие файлы не разбиваются на куски, а идут одним архивом, размер которого ХЗ какой выйдет
примерно так(не тестировалось):
import os
import stat
import zipfile
archive_num = 1
outfile = zipfile.ZipFile('/zips/archive%s.zip' % archive_num, "w")
zsize = 0
for full_name in filelist:
full_name_path = os.path.join(full_name, full_path)
if outfile.fp.tell() > 15728640: # 15mb
outfile.close()
archive_num += 1
outfile = zipfile.ZipFile('/zips/archive%s.zip' % archive_num, "w")
outfile.write(full_name_path,full_name_path,zipfile.ZIP_DEFLATED)
2. Создаем один зип файл, потом режем его на заданые куски, называем например name.zip.001, name.zip.002… и тд…
Плюсы:
- размер томов именно такой как мы хотим
Минусы:
- таки получаем архив открывающийся не любым архиватором а только архиватором/программой поддерживающим разбивку zip(7zip например откроет)
- нужно свободное место на диске равное 2Х<размер архива> Хотя, по идее, это можно решить если писать не на диск, а в память через BytesIO и скидывать на диск по мере заполнения…
както так:
import zipfile
import os
def make_zip(src, zip_name):
'''
ДОбавляем в архив все фалы из папки src
src - имя папки, может содержать полный или относительный путь
zip_name - Имя архива, может содержать полный или относительный путь
'''
zf = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED)
for root, dirs, files in os.walk(src):
for file in files:
f_name = os.path.join(root,file)
zf.write(f_name)
zf.close()
def split_file(f_name, p_size= 1):
'''
Разбить файл на куски размером p_size
f_name - Имя архива, может содержать полный или относительный путь
p_size - размер тома , в данном случае в килобайтах, чтоб проще тестировать
'''
BS = 512 # размер блока которыми читаем из файла
p_size = p_size*1024 # проебразуем в байты
cur_vol = 1 # текущий номер тома
written = 0 # сколько байт записали
with open(f_name, 'rb') as src:
while True:
output_fname = '{}.{}'.format(f_name, str(cur_vol).zfill(3))
output = open(output_fname, 'wb')
while written < p_size:
data = src.read(BS)
if data == b'':
break
output.write(data)
written+=len(data)
print('write', len(data), 'bytes to', output_fname)
else:
output.close()
cur_vol += 1
written = 0
continue
output.close()
break
if __name__ == '__main__':
src_dir = r'd:\temp\test'
make_zip(src_dir, 'testfile2.zip')
split_file('testfile2.zip', 2)
>>>
write 512 bytes to testfile2.zip.001
write 512 bytes to testfile2.zip.001
write 512 bytes to testfile2.zip.001
write 512 bytes to testfile2.zip.001
write 512 bytes to testfile2.zip.002
write 512 bytes to testfile2.zip.002
write 512 bytes to testfile2.zip.002
write 512 bytes to testfile2.zip.002
write 512 bytes to testfile2.zip.003
write 512 bytes to testfile2.zip.003
write 512 bytes to testfile2.zip.003
write 512 bytes to testfile2.zip.003
write 352 bytes to testfile2.zip.004
>>>