Сжатие каталога с помощью 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 слишком запутан для использования.
и только код..
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')