Compresión y descompresión de archivos



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.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#       zipcompressor.py
#       
#       Copyright 2013 Recursos Python - www.recursospython.com
#       
#       

from os.path import dirname, exists
from sys import argv

from zipfile import BadZipfile, ZipFile


PATH = dirname(__file__)

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(PATH, pwd=pwd)
        except RuntimeError:
            pwd = raw_input("Clave para %s: " % filename)
            decompress(filename, pwd=pwd)


def main():
    argc = len(argv)
    
    if argc > 1:
        for filename in argv[1:]:
            if exists(filename):
                try:
                    decompress(filename)
                except BadZipfile:
                    compress(filename)
            else:
                print "No se ha encontrado %s." % filename
    else:
        print u"No se ha encontrado ningún archivo."
    

if __name__ == "__main__":
    main()

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.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#       gzcompressor.py
#       
#       Copyright 2013 Recursos Python - www.recursospython.com
#       
#       

from sys import argv
from os.path import exists

import gzip


def read_file(filename):
    try:
        f = open(filename, "rb")
    except IOError, 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, 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()


def main():
    argc = len(argv)
    
    if argc > 1:
        for filename in argv[1:]:
            if exists(filename):
                if filename.lower().endswith(".gz"):
                    decompress(filename)
                else:
                    compress(filename)
            else:
                print "No se ha encontrado %s." % filename
    else:
        print u"No se ha encontrado ningún archivo."
    

if __name__ == "__main__":
    main()

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:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#       bz2compressor.py
#       
#       Copyright 2013 Recursos Python - www.recursospython.com
#       
#       

from sys import argv
from os.path import exists

import bz2


def read_file(filename):
    try:
        f = open(filename, "rb")
    except IOError, 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, 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))


def main():
    argc = len(argv)
    
    if argc > 1:
        for filename in argv[1:]:
            if exists(filename):
                if filename.lower().endswith(".bz2"):
                    decompress(filename)
                else:
                    compress(filename)
            else:
                print "No se ha encontrado %s." % filename
    else:
        print u"No se ha encontrado ningún archivo."
    

if __name__ == "__main__":
    main()

Descargas

Contiene bz2compressor.py, gzcompressor.py y zipcompressor.py.

Descargar

Versión

Python 2.7



3 comentarios.

Deja un comentario