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.