Wie erstelle ich eine vollständig komprimierte TAR-Datei mit Python?

106

Wie kann ich eine .tar.gz-Datei mit Komprimierung in Python erstellen?

shahjapan
quelle
16
tar komprimiert keine Daten, sondern packt nur die Dateien zusammen. Es ist gzip, das die eigentliche Komprimierung durchführt.
Ignacio Vazquez-Abrams

Antworten:

184

So erstellen Sie ein .tar.gz(aka .tgz) für einen gesamten Verzeichnisbaum:

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))

Dadurch wird ein komprimiertes Teerarchiv erstellt, das einen einzelnen Ordner der obersten Ebene mit demselben Namen und Inhalt wie enthält source_dir.

George V. Reilly
quelle
30
Nur als Hinweis für die Leser, wenn Sie arcname=os.path.basename(source_dir)weglassen, erhalten Sie die gesamte Pfadstruktur source_dirin der TAR-Datei (in den meisten Situationen ist dies wahrscheinlich unpraktisch).
Brōtsyorfuzthrāx
12
Eine zweite Note; Die Verwendung von arcname=os.path.basename(source_dir)still bedeutet, dass das Archiv einen Ordner enthält, der den Inhalt von enthält source_dir. Wenn Sie möchten, dass das Stammverzeichnis des Archivs den Inhalt selbst und nicht den Inhalt eines Ordners enthält, verwenden Sie arcname=os.path.sepstattdessen.
Jonathan H
2
@Sheljohn leider ist dies nicht ganz richtig, denn wenn man verwendet os.path.sep, dann enthält das Archiv den Dienst "." oder "/" Ordner, was normalerweise kein Problem ist, aber manchmal kann es ein Problem sein, wenn Sie dieses Archiv später programmgesteuert verarbeiten. Es scheint der einzig wirklich saubere Weg zu sein os.walk, Dateien einzeln zu erstellen und hinzuzufügen
The Godfather
Verwenden Sie einfach, um die gesamte Verzeichnisstruktur zu entfernen arcname='.'. Keine Notwendigkeit zu verwenden 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()

Wenn Sie eine komprimierte tar.bz2-Datei erstellen möchten, ersetzen Sie einfach den Namen der Dateierweiterung durch ".tar.bz2" und "w: gz" durch "w: bz2".

CNBorn
quelle
10
Sie sollten wirklich with tarfile.open( ..in Python verwenden, anstatt aufzurufen openund closemanuell. Dies ist auch beim Öffnen regulärer Dateien der Fall.
Jonathan H
31

Sie rufen tarfile.open mit auf mode='w:gz', was "Offen für gzip-komprimiertes Schreiben" bedeutet.

Sie möchten wahrscheinlich den Dateinamen (das nameArgument zu open) mit beenden .tar.gz, dies hat jedoch keine Auswirkungen auf die Komprimierungsfähigkeiten.

Übrigens erhalten Sie normalerweise eine bessere Komprimierung mit einem Modus von 'w:bz2', genau wie Sie normalerweise noch besser komprimieren tarkönnen bzip2als mit gzip.

Alex Martelli
quelle
6
Nur eine kurze Anmerkung, dass der Dateiname für bzip2-komprimierte Tarballs mit ".tar.bz2" enden sollte.
Ignacio Vazquez-Abrams
8

In früheren Antworten wird empfohlen, das tarfilePython-Modul zum Erstellen einer .tar.gzDatei in Python zu verwenden. Das ist natürlich eine gute Lösung im Python-Stil, hat aber einen gravierenden Nachteil in der Geschwindigkeit der Archivierung. In dieser Frage wird erwähnt, dass dies tarfileungefähr zweimal langsamer ist als das tarDienstprogramm unter Linux. Nach meiner Erfahrung ist diese Einschätzung ziemlich richtig.

Für eine schnellere Archivierung können Sie den tarBefehl mithilfe des subprocessModuls verwenden:

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

In dieser tar.gz-Datei im geöffneten Ansichtsverzeichnis komprimieren Verwenden Sie zum Lösen 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))

seine Verwendung in der Datei tar.gz komprimieren im Verzeichnis

T GTI
quelle
0

Zusätzlich zur Antwort von @Aleksandr Tukallo können Sie auch die Ausgabe- und Fehlermeldung erhalten (falls dies auftritt). Das Komprimieren eines Ordners mit tarwird in der folgenden Antwort ziemlich gut erklärt .

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
quelle