Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 8, 2019 07:27:59

VIRTOK
Зарегистрирован: 2017-10-23
Сообщения: 77
Репутация: +  0  -
Профиль   Отправить e-mail  

Работа с zip архивом, деление архива на части.

Нужно переписать функцию архивации с помощью питона
На данный момент архивация выполняется 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)

Офлайн

#2 Фев. 8, 2019 14:06:00

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Работа с zip архивом, деление архива на части.

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
>>> 



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Фев. 8, 2019 16:36:50)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version