¿Cómo crear un archivo tar comprimido completo usando Python?

107

¿Cómo puedo crear un archivo .tar.gz con compresión en Python?

shahjapan
fuente
16
tar no comprime datos, simplemente empaqueta los archivos juntos. Es gzip el que realiza la compresión real.
Ignacio Vazquez-Abrams

Respuestas:

186

Para construir un .tar.gz(alias .tgz) para un árbol de directorios completo:

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

Esto creará un archivo tar comprimido con gzip que contiene una única carpeta de nivel superior con el mismo nombre y contenido que source_dir.

George V. Reilly
fuente
31
Solo como una nota para los lectores, si lo omite arcname=os.path.basename(source_dir), le dará la estructura de ruta completa del source_dirarchivo tar (en la mayoría de las situaciones, eso probablemente sea un inconveniente).
Brōtsyorfuzthrāx
12
Una segunda nota; usar arcname=os.path.basename(source_dir)still significa que el archivo contiene una carpeta que contiene el contenido de source_dir. Si desea que la raíz del archivo contenga el contenido en sí mismo y no el contenido dentro de una carpeta, utilice arcname=os.path.sepen su lugar.
Jonathan H
2
@Sheljohn desafortunadamente, esto no es completamente correcto, porque si uno usa os.path.sep, entonces el archivo contendrá el servicio "." o carpeta "/" que no suele ser un problema, pero a veces puede ser un problema si luego procesa este archivo mediante programación. Parece que la única forma realmente limpia es hacer os.walky agregar archivos individualmente
El Padrino
Para deshacerse de toda la estructura de directorios, simplemente use arcname='.'. No es necesario usarlo 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()

Si desea crear un archivo comprimido tar.bz2, simplemente reemplace el nombre de la extensión del archivo con ".tar.bz2" y "w: gz" con "w: bz2".

CNBorn
fuente
10
Realmente debería usar with tarfile.open( ..en Python, en lugar de llamar openy closemanualmente. Este también es el caso al abrir archivos normales.
Jonathan H
31

Usted llama tarfile.open conmode='w:gz' , que significa "Abierto para escritura comprimida gzip".

Probablemente desee terminar el nombre de archivo (el nameargumento de open) con .tar.gz, pero eso no afecta las capacidades de compresión.

Por cierto, generalmente obtienes una mejor compresión con un modo de 'w:bz2', al igual tarque normalmente se puede comprimir incluso mejor bzip2de lo que se puede comprimir gzip.

Alex Martelli
fuente
6
Solo una nota rápida de que el nombre de archivo para los archivos tar comprimidos con bzip2 debe terminar con ".tar.bz2".
Ignacio Vazquez-Abrams
8

Las respuestas anteriores aconsejan usar el tarfilemódulo de Python para crear un .tar.gzarchivo en Python. Obviamente, es una buena solución al estilo de Python, pero tiene un serio inconveniente en la velocidad de archivo. Esta pregunta menciona que tarfilees aproximadamente dos veces más lento que eltar utilidad en Linux. Según mi experiencia, esta estimación es bastante correcta.

Entonces, para un archivado más rápido, puede usar el tarcomando usando el subprocessmódulo:

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

En este archivo tar.gz, comprimir en el directorio de vista abierta En solve, use 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))

su uso en el archivo tar.gz comprimir en el directorio

T GTI
fuente
0

Además de la respuesta de @Aleksandr Tukallo, también puede obtener la salida y el mensaje de error (si ocurre). La compresión de una carpeta usando tarse explica bastante bien en la siguiente respuesta .

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
fuente