Jak stworzyć pełny skompresowany plik tar w Pythonie?


Odpowiedzi:


186

Aby zbudować .tar.gz(aka .tgz) dla całego drzewa katalogów:

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

Spowoduje to utworzenie archiwum tar spakowanego gzipem, zawierającego pojedynczy folder najwyższego poziomu o tej samej nazwie i zawartości co source_dir.


31
Jako uwaga dla czytelników, jeśli pominiesz, arcname=os.path.basename(source_dir)otrzymasz całą strukturę ścieżek source_dirw pliku tar (w większości sytuacji jest to prawdopodobnie niewygodne).
Brōtsyorfuzthrāx

12
Druga uwaga; użycie arcname=os.path.basename(source_dir)nadal oznacza, że ​​archiwum zawiera folder zawierający zawartość source_dir. Jeśli chcesz, aby katalog główny archiwum zawierał samą zawartość, a nie zawartość folderu, użyj arcname=os.path.sepzamiast tego.
Jonathan H

2
@Sheljohn niestety nie jest to do końca poprawne, bo jeśli ktoś użyje os.path.sep, to archiwum będzie zawierało usługę "." lub folder „/”, co zwykle nie stanowi problemu, ale czasami może to być problem, jeśli później programowo przetworzysz to archiwum. Wydaje się, że jedynym naprawdę czystym sposobem jest robienie os.walki dodawanie plików indywidualnie
The Godfather

Aby pozbyć się całej struktury katalogów, po prostu użyj arcname='.'. Nie ma potrzeby używania 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()

Jeśli chcesz utworzyć skompresowany plik tar.bz2, po prostu zamień rozszerzenie pliku na „.tar.bz2” i „w: gz” na „w: bz2”.


10
Naprawdę powinieneś używać with tarfile.open( ..w Pythonie, zamiast dzwonić openi closeręcznie. Dzieje się tak również w przypadku otwierania zwykłych plików.
Jonathan H

31

Nazywasz tarfile.open z mode='w:gz', czyli „Otwórz za gzip skompresowanej formie pisemnej.”

Prawdopodobnie będziesz chciał zakończyć nazwę pliku ( nameargument do open) .tar.gz, ale to nie wpływa na możliwości kompresji.

Przy okazji, zwykle uzyskujesz lepszą kompresję w trybie 'w:bz2', tak jak tarzwykle można kompresować nawet lepiej bzip2niż w przypadku gzip.


6
Krótka uwaga, że ​​nazwa pliku dla archiwów skompresowanych za pomocą bzip2 powinna kończyć się na „.tar.bz2”.
Ignacio Vazquez-Abrams

8

Poprzednie odpowiedzi zalecają użycie tarfilemodułu Python do tworzenia .tar.gzpliku w Pythonie. To oczywiście dobre rozwiązanie w stylu Pythona, ale ma poważną wadę w szybkości archiwizacji. To pytanie wspomina, że tarfilejest około dwa razy wolniejsze niż tarnarzędzie w systemie Linux. Z mojego doświadczenia wynika, że ​​ta ocena jest całkiem poprawna.

A więc dla szybszej archiwizacji możesz skorzystać z tarpolecenia za pomocą subprocessmodułu:

subprocess.call(['tar', '-czf', output_filename, file_to_archive])

0

W tym pliku tar.gz skompresuj w otwartym katalogu widoku W rozwiązaniu użyj 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))

jego użycie w pliku tar.gz skompresuj w katalogu


0

Oprócz odpowiedzi @Aleksandr Tukallo, możesz również uzyskać dane wyjściowe i komunikat o błędzie (jeśli wystąpi). Poniższa odpowiedźtar dość dobrze wyjaśnia kompresję folderu za pomocą .

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()}")       
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.