Найти - Пользователи
Полная версия: Работа с zip архивом, деление архива на части.
Начало » Python для новичков » Работа с zip архивом, деление архива на части.
1
VIRTOK
Нужно переписать функцию архивации с помощью питона
На данный момент архивация выполняется 7z . Но если на компьютере пользователя нет 7z то архивация невозможна. Кроме того нужно организовать деление архивов на части используя
zipfile
 import os
LocalDir = os.getcwd() # Путь к локальной директории
ArchZip= str(LocalDir+"\\Tools\\7z.exe")#Путь где расположен 7z
#Создать архив
def Make_zip(ArchZip_location,Name_ArchZip,Foler_Zip_Location,Paht_size_ArchZip="99"):
    #ArchZip_location - расположение архива
    #Name_ArchZip - имя частей архива
    #Foler_Zip_Location- путь к папке которую нужно запаковать
    #Paht_size_ArchZip - Размер части архива , по умолчанию 99мб. Параметр можно не задавать при вызове функции
     make_zip = str(ArchZip + " a " + "-tzip "+ "-v"+Paht_size_ArchZip+"m " + LocalDir + ArchZip_location + Name_ArchZip+".zip" + " -r " + LocalDir + Foler_Zip_Location +"*" + " t " ">> log_Make_zip.txt" )
     #print(make_zip)
     return os.system(make_zip)
PEHDOM
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
>>> 

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB