Сжатие каталога с помощью shutil.make archive () при сохранении структуры каталогов

Я пытаюсь zip каталог под названием test_dicoms на zip-файл с именем test_dicoms.zip использовать следующий код:

shutil.make_archive('/home/code/test_dicoms','zip','/home/code/test_dicoms')

проблема в том, что когда я распаковываю его, все файлы, которые были в /test_dicoms/ извлекаются в /home/code/ вместо папки /test_dicoms/ и все это содержит файлы, которые извлекаются в /home/code/. Так что /test_dicoms/ есть файл под названием foo.txt и после того, как я zip и распаковать foo.txtпуть /home/code/foo.txt в противоположность /home/code/test_dicoms/foo.txt. Как это исправить? Также, некоторые каталоги, с которыми я работаю, очень большие. Нужно ли добавлять что-либо в мой код, чтобы сделать его ZIP64, или функция достаточно умна, чтобы сделать это автоматически?

вот что в настоящее время в созданном архиве:

[gwarner@jazz gwarner]$ unzip -l test_dicoms.zip
Archive: test_dicoms.zip
Length    Date       Time  Name
--------- ---------- ----- ----
    93324 09-17-2015 16:05 AAscout_b_000070
    93332 09-17-2015 16:05 AAscout_b_000125
    93332 09-17-2015 16:05 AAscout_b_000248

2 ответов


используя термины в документации, указано root_dir, а не base_dir. Попробуйте указать base_dir вот так:

shutil.make_archive('/home/code/test_dicoms',
                    'zip',
                    '/home/code/',
                    'test_dicoms')

чтобы ответить на ваш второй вопрос, это зависит от версии Python, который вы используете. Начиная с Python 3.4, расширения ZIP64 будут доступны по умолчанию. До Python 3.4,make_archive не будет автоматически создавать файл с расширениями ZIP64. Если вы используете более старую версию Python и хотите ZIP64, вы можете вызвать базовый zipfile.ZipFile() напрямую.

если вы используете zipfile.ZipFile() напрямую, минуя shutil.make_archive(), вот пример:

import zipfile
import os

d = '/home/code/test_dicoms'

os.chdir(os.path.dirname(d))
with zipfile.ZipFile(d + '.zip',
                     "w",
                     zipfile.ZIP_DEFLATED,
                     allowZip64=True) as zf:
    for root, _, filenames in os.walk(os.path.basename(d)):
        for name in filenames:
            name = os.path.join(root, name)
            name = os.path.normpath(name)
            zf.write(name, name)

ссылки:


Я сам написал функцию-оболочку, потому что shutil.make_archive слишком запутан для использования.

вот он http://www.seanbehan.com/how-to-use-python-shutil-make_archive-to-zip-up-a-directory-recursively-including-the-root-folder/

и только код..

import os, shutil
def make_archive(source, destination):
        base = os.path.basename(destination)
        name = base.split('.')[0]
        format = base.split('.')[1]
        archive_from = os.path.dirname(source)
        archive_to = os.path.basename(source.strip(os.sep))
        shutil.make_archive(name, format, archive_from, archive_to)
        shutil.move('%s.%s'%(name,format), destination)

make_archive('/path/to/folder', '/path/to/folder.zip')