Bagaimana cara membuat file tar terkompresi penuh menggunakan Python?

107

Bagaimana cara membuat file .tar.gz dengan kompresi dengan Python?

shahjapan
sumber
16
tar tidak mengkompres data, ia hanya mengemas file bersama-sama. Gziplah yang melakukan kompresi sebenarnya.
Ignacio Vazquez-Abrams

Jawaban:

186

Untuk membangun .tar.gz(alias .tgz) untuk seluruh pohon direktori:

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

Ini akan membuat arsip tar gzip yang berisi satu folder tingkat atas dengan nama dan konten yang sama seperti source_dir.

George V. Reilly
sumber
31
Hanya sebagai catatan bagi pembaca, jika Anda membiarkannya keluar arcname=os.path.basename(source_dir)maka itu akan memberi Anda seluruh struktur jalur source_dirdalam file tar (dalam banyak situasi, itu mungkin tidak nyaman).
Brōtsyorfuzthrāx
12
Catatan kedua; menggunakan arcname=os.path.basename(source_dir)masih berarti arsip berisi folder yang berisi konten source_dir. Jika Anda ingin root arsip berisi konten itu sendiri, dan bukan konten di dalam folder, gunakan arcname=os.path.sepsaja.
Jonathan H
2
@Sheljohn sayangnya, ini tidak sepenuhnya benar, karena jika seseorang menggunakan os.path.sep, maka arsip akan berisi layanan "." atau folder "/" yang biasanya tidak menjadi masalah, tetapi terkadang dapat menjadi masalah jika nanti Anda memproses arsip ini secara terprogram. Tampaknya satu-satunya cara yang benar-benar bersih adalah dengan melakukan os.walkdan menambahkan file satu per satu
The Godfather
Untuk menghilangkan semua struktur direktori, cukup gunakan arcname='.'. Tidak perlu digunakan 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()

Jika Anda ingin membuat file terkompresi tar.bz2, cukup ganti nama ekstensi file dengan ".tar.bz2" dan "w: gz" dengan "w: bz2".

CNBorn
sumber
10
Anda harus benar-benar menggunakan with tarfile.open( ..Python, daripada menelepon opendan closesecara manual. Ini juga terjadi saat membuka file biasa.
Jonathan H
31

Anda memanggil tarfile.open dengan mode='w:gz', yang berarti "Terbuka untuk tulisan terkompresi gzip."

Anda mungkin ingin mengakhiri nama file ( nameargumen ke open) dengan .tar.gz, tetapi itu tidak mempengaruhi kemampuan kompresi.

BTW, Anda biasanya mendapatkan kompresi yang lebih baik dengan mode 'w:bz2', seperti tarbiasanya dapat mengompres dengan lebih baik bzip2daripada yang dapat dikompres gzip.

Alex Martelli
sumber
6
Sebagai catatan singkat, nama file untuk tarball yang dikompresi bzip2 harus diakhiri dengan ".tar.bz2".
Ignacio Vazquez-Abrams
8

Jawaban sebelumnya menyarankan penggunaan tarfilemodul Python untuk membuat .tar.gzfile dengan Python. Itu jelas merupakan solusi yang bagus dan bergaya Python, tetapi memiliki kelemahan serius dalam kecepatan pengarsipan. Pertanyaan ini menyebutkan bahwa tarfilekira-kira dua kali lebih lambat daripada tarutilitas di Linux. Menurut pengalaman saya, perkiraan ini cukup tepat.

Jadi untuk pengarsipan lebih cepat Anda dapat menggunakan tarperintah menggunakan subprocessmodul:

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

Dalam file tar.gz ini kompres dalam direktori tampilan terbuka Dalam menyelesaikannya gunakan 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))

penggunaannya dalam kompres file tar.gz dalam direktori

T GTI
sumber
0

Selain jawaban @Aleksandr Tukallo, Anda juga bisa mendapatkan output dan pesan kesalahan (jika terjadi). Mengompresi folder menggunakan tardijelaskan dengan cukup baik pada jawaban berikut .

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
sumber