Compresión y descompresión de archivos zip, gz y bz2

Compresión y descompresión de archivos zip, gz y bz2

Descarga: compresion_y_descompresion.zip.

Mediante los módulos integrados por defecto zipfile, gzip y bz2 Python nos permite realizar compresiones y descompresiones con los diversos algoritmos.

zipfile

Este módulo provee herramientas para crear, escribir, leer, añadir y listar un archivo ZIP. Cualquier uso avanzado del mismo requerirá del entendimiento del formato, definido en la PKZIP Application Note.

El siguiente ejemplo, extraído de la documentación oficial, muestra cómo comprimir un archivo de texto llamado eggs.txt en un ZIP spam.zip.

from zipfile import ZipFile

with ZipFile('spam.zip', 'w') as myzip:
    myzip.write('eggs.txt')

Nótese la sentencia with, que al ser utilizada en este ejemplo myzip es cerrado al finalizar incluso si ocurre una excepción. De todas maneras, puede expresarse de la forma tradicional:

myzip = ZipFile('spam.zip', 'w')
myzip.write('eggs.txt')
myzip.close()

Luego, para extraer el mismo archivo:

with ZipFile('spam.zip') as myzip:
    myzip.extractall()

Por último, un script que recibe como argumento uno o más archivos, los cuales comprime y, en caso de estar comprimido, descomprime solicitando la contraseña de ser necesario.

# zipcompressor.py

from zipfile import BadZipfile, ZipFile
import os
import sys


def compress(filename):
    with ZipFile(filename + ".zip", "w") as f:
        arcname = filename.replace("\\", "/")
        arcname = arcname[arcname.rfind("/") + 1:]
        f.write(filename, arcname)


def decompress(filename, pwd=None):
    with ZipFile(filename) as f:
        try:
            f.extractall(os.getcwd(), pwd=pwd)
        except RuntimeError:
            pwd = input("Clave para %s: " % filename)
            decompress(filename, pwd=pwd)


if len(sys.argv) > 1:
    for filename in sys.argv[1:]:
        if os.path.exists(filename):
            try:
                decompress(filename)
            except BadZipfile:
                compress(filename)
        else:
            print("No se ha encontrado", filename)
else:
    print("No se ha encontrado ningún archivo.")

Clases, funciones, código de fuente, y demás documentación puede encontrarse en este enlace.

gzip

Este módulo provee una simple interfaz para comprimir y descomprimir archivos al igual que lo harían los programas gzip y gunzip de GNU. Al igual que zipfile, la compresión de datos es brindada por el módulo zlib.

Utilizar la clase gzip.GzipFile es similar a tratar con archivos retornados por la función open, por lo que al llamar a los métodos write y read, el contenido será comprimido y descomprimido, repectivamente.

Ejemplo 1: leer un archivo comprimido.

import gzip
f = gzip.open('file.txt.gz', 'rb')
file_content = f.read()
f.close()

Ejemplo 2: crear un archivo GZIP.

import gzip
content = "Diversos datos a ser comprimidos."
f = gzip.open('file.txt.gz', 'wb')
f.write(content)
f.close()

Más ejemplos en la documentación.

Finalmente, el mismo script de compresión y descompresión dado a conocer anteriormente, para archivos GZIP.

# gzcompressor.py

import gzip
import os
import sys


def read_file(filename):
    try:
        f = open(filename, "rb")
    except IOError as e:
        print(e.errno, e.message)
    else:
        data = f.read()
        f.close()
        return data


def write_file(filename, data):
    try:
        f = open(filename, "wb")
    except IOError as e:
        print(e.errno, e.message)
    else:
        f.write(data)
        f.close()


def compress(filename):
    data = read_file(filename)
    
    if data is not None:
        f = gzip.open(filename + ".gz", "wb")
        f.write(data)
        f.close()


def decompress(filename):
    f = gzip.open(filename)
    write_file(filename[:filename.rfind(".gz")], f.read())
    f.close()


if len(sys.argv) > 1:
    for filename in sys.argv[1:]:
        if os.path.exists(filename):
            if filename.lower().endswith(".gz"):
                decompress(filename)
            else:
                compress(filename)
        else:
            print("No se ha encontrado", filename)
else:
    print("No se ha encontrado ningún archivo.")

bz2

Brinda una interfaz comprensiva para la librería de compresión bz2. Incorpora una interfaz de archivo completa, compresión y descompresión rápida y secuencial.

Ejemplo de compresión y descompresión rápida (respectivamente), gracias a las funciones compress() y decompress(). La documentación completa puede encontrarse en este enlace.

compress.py

import bz2

f_in = open("test.txt", "rb")
f_out = open("test.txt.bz2", "wb")
f_out.write(bz2.compress(f_in.read()))
f_out.close()
f_in.close()

decompress.py

import bz2

f_in = open("test.txt.bz2", "rb")
f_out = open("test.txt", "wb")
f_out.write(bz2.decompress(f_in.read()))
f_out.close()
f_in.close()

Y para finalizar, el script análogo utilizando bz2:

# bz2compressor.py

import bz2
import os
import sys


def read_file(filename):
    try:
        f = open(filename, "rb")
    except IOError as e:
        print(e.errno, e.message)
    else:
        data = f.read()
        f.close()
        return data


def write_file(filename, data):
    try:
        f = open(filename, "wb")
    except IOError as e:
        print(e.errno, e.message)
    else:
        f.write(data)
        f.close()


def compress(filename):
    data = read_file(filename)
    
    if data is not None:
        f = open(filename + ".bz2", "wb")
        f.write(bz2.compress(data))
        f.close()


def decompress(filename):
    data = read_file(filename)
    
    if data is not None:
        write_file(filename[:filename.rfind(".bz2")],
                   bz2.decompress(data))


if len(sys.argv) > 1:
    for filename in sys.argv[1:]:
        if os.path.exists(filename):
            if filename.lower().endswith(".bz2"):
                decompress(filename)
            else:
                compress(filename)
        else:
            print("No se ha encontrado", filename)
else:
    print("No se ha encontrado ningún archivo.")

Curso online 👨‍💻

¡Ya lanzamos el curso oficial de Recursos Python en Udemy! Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter en 2024.

Consultoría 💡

Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.

3 comentarios.

Deja una respuesta