gzip en Python: comprime archivos .gz

Publicado el: 17/08/2026
Tempo de leitura: 4 minutos
Row of colorful office binders neatly arranged on a shelf, ideal for organization concepts.

El módulo gzip en Python permite leer y escribir streams GZIP mediante una interfaz parecida a la de un archivo normal. Utiliza DEFLATE a través de zlib y ofrece funciones en memoria, la clase GzipFile, wrappers de texto y una interfaz de línea de comandos.

GZIP es compatible con herramientas Unix, servidores web, pipelines de datos y formatos de distribución. Comprime un stream lógico, no funciona como contenedor de múltiples rutas. Para conservar un árbol de directorios, normalmente se crea TAR y luego se comprime con GZIP.

Cuándo usar gzip

Usa GZIP para logs, JSON Lines, CSV, respuestas HTTP y backups de un solo stream. Para controlar DEFLATE a bajo nivel, consulta zlib en Python. Si el tamaño final importa más que la velocidad, compáralo con lzma en Python.

Comprime bytes de una vez

import gzip

datos = ("registro de acceso\n" * 2000).encode("utf-8")
comprimido = gzip.compress(datos, compresslevel=6)
restaurado = gzip.decompress(comprimido)

assert restaurado == datos
print(len(datos), len(comprimido))

Las funciones mantienen entrada y salida completas en memoria. En Python 3.14, gzip.compress() usa mtime=0 por defecto, por lo que la salida no depende de la hora de creación. Pasa mtime=None para guardar el timestamp actual.

Genera salida reproducible

Un build reproducible necesita que el mismo contenido produzca exactamente los mismos bytes. El timestamp variable del encabezado lo impedía. La función de conveniencia ahora favorece resultados deterministas:

import gzip
import hashlib

artefacto = gzip.compress(b"version=1\n", mtime=0)
print(hashlib.sha256(artefacto).hexdigest())

Al construir GzipFile directamente, indica mtime=0 cuando este requisito sea importante.

Escribe texto comprimido

import gzip

with gzip.open("eventos.log.gz", "wt", encoding="utf-8", compresslevel=6) as archivo:
    archivo.write("servicio iniciado\n")
    archivo.write("tarea completada\n")

Los modos de texto crean un io.TextIOWrapper. Especifica la codificación y usa xt cuando un destino existente deba provocar un error.

Lee línea por línea

import gzip

with gzip.open("eventos.log.gz", "rt", encoding="utf-8") as archivo:
    for numero, linea in enumerate(archivo, 1):
        procesar(numero, linea.rstrip())

La iteración evita materializar todo el texto y complementa las técnicas para leer archivos gigantes con Python. Aun así, limita el número de líneas y los bytes expandidos.

Comprime un archivo existente

import gzip
import shutil

with open("datos.csv", "rb") as origen:
    with gzip.open("datos.csv.gz", "wb", compresslevel=6) as destino:
        shutil.copyfileobj(origen, destino, length=1024 * 1024)

La copia se realiza por bloques. En producción, escribe primero en una ruta temporal, cierra el archivo y renómbralo de forma atómica para que los lectores no vean contenido parcial.

Usa GzipFile con BytesIO

import gzip
import io

buffer = io.BytesIO()
with gzip.GzipFile(fileobj=buffer, mode="wb", compresslevel=6, mtime=0) as gz:
    gz.write(b"contenido" * 1000)

payload = buffer.getvalue()

Cerrar GzipFile no cierra el fileobj. Así puedes recuperar el buffer o añadir información de protocolo después del miembro comprimido.

Metadatos del encabezado

El encabezado puede incluir tiempo de modificación y nombre original. Cuando se pasa fileobj, filename se utiliza solo para el encabezado. Evita exponer usuarios, rutas temporales o estructura interna.

Miembros concatenados

gzip.decompress() admite varios miembros GZIP concatenados. El modo append también agrega un miembro al final. Es válido, pero herramientas externas pueden mostrar o procesar los miembros de forma distinta. Comprueba la interoperabilidad.

Maneja entradas inválidas

Los datos dañados pueden lanzar gzip.BadGzipFile, EOFError o zlib.error.

import gzip
import zlib

try:
    with gzip.open("entrada.gz", "rb") as archivo:
        datos = archivo.read()
except (gzip.BadGzipFile, EOFError, zlib.error) as error:
    raise ValueError("entrada GZIP inválida") from error

Registra un identificador seguro, no el contenido ni rutas sensibles.

Limita la descompresión

gzip.decompress() devuelve toda la salida y no recibe un límite total. No la uses sin control sobre uploads grandes. Lee bloques con GzipFile y cuenta:

import gzip

limite = 100 * 1024 * 1024
total = 0

with gzip.open("upload.gz", "rb") as archivo:
    while bloque := archivo.read(64 * 1024):
        total += len(bloque)
        if total > limite:
            raise ValueError("el contenido expandido superó el límite")
        consumir(bloque)

Limita también tamaño comprimido, tiempo de CPU y cantidad de miembros. Los checks de GZIP detectan corrupción accidental, pero no autentican el origen.

Niveles de compresión

  • 0: almacena sin comprimir.
  • 1: mayor velocidad y archivo más grande.
  • 6: equilibrio habitual y valor de la CLI.
  • 9: intento más lento de máxima compresión.

Imágenes, vídeo y muchos PDF ya están comprimidos. Mide contenido representativo antes de seleccionar el nivel.

GZIP no archiva directorios

GZIP representa un stream. Para guardar nombres, permisos y carpetas, crea TAR antes. ZIP combina contenedor y compresión; las diferencias prácticas aparecen en la guía de ZIP con Python.

Interfaz de línea de comandos

Ejecuta python -m gzip para comprimir o descomprimir. La CLI conserva el archivo de entrada y acepta --fast, --best y --decompress. La API es preferible cuando necesitas rutas, límites y reemplazo atómico.

Estrategia de pruebas

Prueba entrada vacía, Unicode codificado, streams truncados, miembros concatenados, niveles distintos, encabezados deterministas y límites de salida.

import gzip

def test_gzip_reproducible():
    primero = gzip.compress(b"abc", mtime=0)
    segundo = gzip.compress(b"abc", mtime=0)
    assert primero == segundo
    assert gzip.decompress(primero) == b"abc"

Buenas prácticas

  • Usa context managers.
  • Especifica modo y codificación.
  • Usa mtime=0 para artefactos reproducibles.
  • Escribe de forma atómica.
  • Limita entrada, salida, miembros y CPU.
  • No incluyas nombres sensibles.
  • Prueba interoperabilidad.
  • No confundas integridad con autenticación.

Conclusión

gzip en Python es una opción práctica para streams comprimidos compatibles. Admite memoria, archivos, texto y buffers arbitrarios, y Python 3.14 genera salida determinista de una sola operación por defecto.

Consulta la documentación oficial de gzip y la RFC 1952. Para configurar niveles por entorno, revisa configparser en Python.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Código asíncrono que representa asyncio.eager_task_factory en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    asyncio.eager_task_factory: reduce overhead de tareas

    Aprende asyncio.eager_task_factory en Python para reducir overhead, entender cambios de orden y optimizar corrutinas cortas con seguridad.

    Ler mais

    Tempo de leitura: 5 minutos
    14/09/2026
    Desarrollador trabajando con timestamps UTC y calendar.timegm en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    calendar.timegm: convierte UTC a timestamp Unix

    Aprende calendar.timegm en Python para convertir fechas UTC en timestamps Unix y evitar errores de zona horaria y unidades.

    Ler mais

    Tempo de leitura: 6 minutos
    14/09/2026
    Programador analizando código para identificar tipos MIME de archivos con Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    mimetypes.guess_file_type: detecta tipos MIME

    Aprende mimetypes.guess_file_type en Python para detectar tipos MIME en rutas, URLs, uploads y respuestas HTTP con fallbacks seguros.

    Ler mais

    Tempo de leitura: 4 minutos
    13/09/2026
    Componentes de servidor que representan intérpretes Python aislados ejecutándose en paralelo
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    InterpreterPoolExecutor: paralelismo real en Python

    Aprende InterpreterPoolExecutor en Python para tareas CPU-bound, intérpretes aislados, paralelismo real y concurrencia segura.

    Ler mais

    Tempo de leitura: 6 minutos
    13/09/2026
    Microprocesador que representa las CPU disponibles para un proceso Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    os.process_cpu_count: cuenta CPUs disponibles

    Aprende os.process_cpu_count en Python para dimensionar workers según las CPU disponibles para el proceso.

    Ler mais

    Tempo de leitura: 4 minutos
    12/09/2026
    Portátil con código digital que representa datos BLOB en SQLite
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    sqlite3.Blob: lee BLOBs sin cargar todo en memoria

    Aprende sqlite3.Blob en Python para leer y escribir BLOBs por partes, reducir memoria y manejar datos binarios en SQLite.

    Ler mais

    Tempo de leitura: 5 minutos
    12/09/2026