it-swarm.com.de

Verzeichnis komprimieren mit shutil.make_archive () unter Beibehaltung der Verzeichnisstruktur

Ich versuche, ein Verzeichnis mit dem Namen test_dicoms mit dem folgenden Code in eine Zip-Datei mit dem Namen test_dicoms.Zip zu komprimieren:

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

Das Problem ist, dass beim Entpacken alle Dateien in /test_dicoms/ anstelle des Ordners /home/code/ in /test_dicoms/ extrahiert werden und alle darin enthaltenen Dateien in /home/code/ extrahiert werden. /test_dicoms/ hat also eine Datei mit dem Namen foo.txt und nach dem Komprimieren und Entpacken von foo.txt lautet der Pfad /home/code/foo.txt im Gegensatz zu /home/code/test_dicoms/foo.txt. Wie behebe ich das? Außerdem sind einige der Verzeichnisse, mit denen ich arbeite, sehr groß. Muss ich meinem Code irgendetwas hinzufügen, damit er Zip64 wird, oder ist die Funktion intelligent genug, um das automatisch zu tun?

Folgendes wird aktuell im Archiv erstellt:

[[email protected] 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
18
G Warner

Sie haben mit den Begriffen in der Dokumentation ein root_dir angegeben, aber kein base_dir. Geben Sie das base_dir wie folgt an: 

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

Um Ihre zweite Frage zu beantworten, hängt es von der verwendeten Python-Version ab. Ab Python 3.4 sind standardmäßig Zip64-Erweiterungen verfügbar. Vor Python 3.4 erstellt make_archive eine Datei mit Zip64-Erweiterungen nicht automatisch. Wenn Sie eine ältere Python-Version verwenden und Zip64 verwenden möchten, können Sie die zugrunde liegende zipfile.ZipFile() direkt aufrufen.

Wenn Sie zipfile.ZipFile() direkt verwenden und shutil.make_archive() umgehen, finden Sie hier ein Beispiel:

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)

Referenz: 

28
Robᵩ

Ich habe selbst eine Wrapper-Funktion geschrieben, weil shutil.make_archive zu verwirrend ist. 

Hier ist es http://www.seanbehan.com/how-to-use-python-shutil-make_archive-to-Zip-up-a-directory-rekursiv- einschließlich-der-wurzelordner/

Und nur der Code .. 

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')
2
seanbehan