Odpowiedzi:
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
.
arcname=os.path.basename(source_dir)
otrzymasz całą strukturę ścieżek source_dir
w pliku tar (w większości sytuacji jest to prawdopodobnie niewygodne).
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.sep
zamiast tego.
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.walk
i dodawanie plików indywidualnie
arcname='.'
. Nie ma potrzeby używania os.walk
.
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”.
with tarfile.open( ..
w Pythonie, zamiast dzwonić open
i close
ręcznie. Dzieje się tak również w przypadku otwierania zwykłych plików.
Nazywasz tarfile.open z mode='w:gz'
, czyli „Otwórz za gzip skompresowanej formie pisemnej.”
Prawdopodobnie będziesz chciał zakończyć nazwę pliku ( name
argument 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 tar
zwykle można kompresować nawet lepiej bzip2
niż w przypadku gzip
.
Poprzednie odpowiedzi zalecają użycie tarfile
modułu Python do tworzenia .tar.gz
pliku w Pythonie. To oczywiście dobre rozwiązanie w stylu Pythona, ale ma poważną wadę w szybkości archiwizacji. To pytanie wspomina, że tarfile
jest około dwa razy wolniejsze niż tar
narzę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 tar
polecenia za pomocą subprocess
modułu:
subprocess.call(['tar', '-czf', output_filename, file_to_archive])
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()}")