J'essaie de compresser un répertoire appelé test_dicoms
dans un fichier Zip nommé test_dicoms.Zip
à l'aide du code suivant:
shutil.make_archive('/home/code/test_dicoms','Zip','/home/code/test_dicoms')
Le problème est que lorsque je décompresse le fichier, tous les fichiers qui étaient dans /test_dicoms/
sont extraits dans /home/code/
au lieu du dossier /test_dicoms/
et tous les fichiers qu'il contient sont extraits dans /home/code/
. Donc /test_dicoms/
a un fichier appelé foo.txt
et après I Zip et décompresser le chemin de foo.txt
est /home/code/foo.txt
par opposition à /home/code/test_dicoms/foo.txt
. Comment puis-je réparer ça? En outre, certains des répertoires avec lesquels je travaille sont très volumineux. Dois-je ajouter quelque chose à mon code pour le rendre Zip64 ou la fonction est-elle assez intelligente pour le faire automatiquement?
Voici ce qui est actuellement dans les archives créées:
[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
En utilisant les termes de la documentation, vous avez spécifié un root_dir, mais pas un base_dir. Essayez de spécifier le base_dir comme ceci:
shutil.make_archive('/home/code/test_dicoms',
'Zip',
'/home/code/',
'test_dicoms')
Pour répondre à votre deuxième question, cela dépend de la version de Python que vous utilisez. À partir de Python 3.4, les extensions Zip64 seront disponibles par défaut. Avant Python 3.4, make_archive
ne créera pas automatiquement un fichier avec des extensions Zip64. Si vous utilisez une ancienne version de Python et que vous voulez Zip64, vous pouvez appeler directement la fonction zipfile.ZipFile()
sous-jacente.
Si vous choisissez d'utiliser zipfile.ZipFile()
directement, en contournant shutil.make_archive()
, voici un exemple:
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)
Référence:
J'ai moi-même écrit une fonction wrapper parce que shutil.make_archive est trop compliqué à utiliser.
Et juste le 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')