Comment créer un fichier tar compressé complet en utilisant Python?

107

Comment créer un fichier .tar.gz avec compression en Python?

shahjapan
la source
16
tar ne compresse pas les données, il rassemble simplement les fichiers. C'est gzip qui effectue la compression réelle.
Ignacio Vazquez-Abrams

Réponses:

186

Pour créer un .tar.gz(aka .tgz) pour une arborescence de répertoires entière:

import tarfile
import os.path

def make_tarfile(output_filename, source_dir):
    with tarfile.open(output_filename, "w:gz") as tar:
        tar.add(source_dir, arcname=os.path.basename(source_dir))

Cela créera une archive tar gzippée contenant un seul dossier de niveau supérieur avec le même nom et le même contenu que source_dir.

George V. Reilly
la source
31
Tout comme une note aux lecteurs, si vous omettez, arcname=os.path.basename(source_dir)cela vous donnera la structure de chemin complète du source_dirfichier tar (dans la plupart des situations, c'est probablement gênant).
Brōtsyorfuzthrāx
12
Une deuxième note; utiliser arcname=os.path.basename(source_dir)encore signifie que l'archive contient un dossier contenant le contenu de source_dir. Si vous souhaitez que la racine de l'archive contienne le contenu proprement dit, et non le contenu d'un dossier, utilisez à la arcname=os.path.sepplace.
Jonathan H
2
@Sheljohn malheureusement, ce n'est pas tout à fait correct, car si on utilise os.path.sep, l'archive contiendra le service "." ou dossier "/" qui n'est généralement pas un problème, mais parfois cela peut être un problème si vous traitez ultérieurement cette archive par programme. Il semble que le seul moyen vraiment propre est de faire os.walket d'ajouter des fichiers individuellement
The Godfather
Pour vous débarrasser de toute la structure de répertoires, utilisez simplement arcname='.'. Pas besoin d'utiliser os.walk.
edouardtheron
85
import tarfile
tar = tarfile.open("sample.tar.gz", "w:gz")
for name in ["file1", "file2", "file3"]:
    tar.add(name)
tar.close()

Si vous souhaitez créer un fichier compressé tar.bz2, remplacez simplement le nom de l'extension de fichier par ".tar.bz2" et "w: gz" par "w: bz2".

CNBorn
la source
10
Vous devriez vraiment utiliser with tarfile.open( ..en Python, au lieu d'appeler openet closemanuellement. C'est également le cas lors de l'ouverture de fichiers normaux.
Jonathan H
31

Vous appelez tarfile.open avecmode='w:gz' , ce qui signifie «Ouvrir pour l'écriture compressée gzip».

Vous voudrez probablement terminer le nom de fichier (l' nameargument vers open) par .tar.gz, mais cela n'affecte pas les capacités de compression.

BTW, vous obtenez généralement une meilleure compression avec un mode de 'w:bz2', tout comme tarpeut généralement compresser encore mieux avec bzip2qu'il ne peut compresser avec gzip.

Alex Martelli
la source
6
Juste une petite note que le nom de fichier pour les archives tar compressées par bzip2 doit se terminer par ".tar.bz2".
Ignacio Vazquez-Abrams
8

Les réponses précédentes conseillent d'utiliser le tarfilemodule Python pour créer un.tar.gz fichier en Python. C'est évidemment une bonne solution de style Python, mais elle présente un sérieux inconvénient en termes de rapidité d'archivage. Cette question mentionne que tarfilec'est environ deux fois plus lent que l' tarutilitaire sous Linux. D'après mon expérience, cette estimation est assez correcte.

Donc, pour un archivage plus rapide, vous pouvez utiliser la tarcommande en utilisant le subprocessmodule:

subprocess.call(['tar', '-czf', output_filename, file_to_archive])
Aleksandr Tukallo
la source
0

Dans ce fichier tar.gz, compressez dans le répertoire de vue ouvert. Dans la résolution, utilisez os.path.basename (file_directory)

with tarfile.open("save.tar.gz","w:gz"):
      for file in ["a.txt","b.log","c.png"]:
           tar.add(os.path.basename(file))

son utilisation dans le fichier tar.gz compresser dans le répertoire

T GTI
la source
0

En plus de la réponse de @Aleksandr Tukallo, vous pouvez également obtenir la sortie et le message d'erreur (le cas échéant). La compression d'un dossier en utilisant tarest assez bien expliquée dans la réponse suivante .

import traceback
import subprocess

try:
    cmd = ['tar', 'czfj', output_filename, file_to_archive]
    output = subprocess.check_output(cmd).decode("utf-8").strip() 
    print(output)          
except Exception:       
    print(f"E: {traceback.format_exc()}")       
alper
la source