lzma en Python: comprime archivos XZ

Publicado el: 17/08/2026
Tempo de leitura: 4 minutos
Neatly arranged blue office binders labeled with dates and names for organized storage.

El módulo lzma en Python ofrece compresión y descompresión con LZMA y LZMA2. Admite archivos modernos .xz, el formato antiguo .lzma y streams RAW configurados con filtros explícitos. Incluye funciones de una sola operación, objetos incrementales y una interfaz de archivo parecida a bz2.

LZMA suele producir archivos menores que gzip o bzip2, pero necesita más CPU y puede consumir mucha memoria. El preset 9 puede llevar al compresor a usar cientos de megabytes. El preset predeterminado 6 es un punto de partida más seguro y la configuración final debe basarse en pruebas con datos representativos.

Cuándo conviene lzma

Usa lzma cuando necesites compatibilidad XZ, cuando el tamaño final importe más que la velocidad máxima o cuando generes datasets de archivo que no se abran continuamente. Para otra alternativa eficaz en texto, consulta bz2 en Python.

Comprime datos en memoria

import lzma

datos = ("registro de auditoría\n" * 2000).encode("utf-8")
comprimido = lzma.compress(datos, preset=6)
restaurado = lzma.decompress(comprimido)

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

lzma.compress() crea XZ por defecto. Es cómodo para cargas pequeñas, pero entrada y salida permanecen en memoria. Para grandes volúmenes, utiliza archivos o procesamiento incremental.

Escribe un archivo XZ de texto

import lzma

with lzma.open("eventos.log.xz", "wt", encoding="utf-8", preset=6) as archivo:
    archivo.write("inicio del proceso\n")
    archivo.write("proceso completado\n")

Los modos siguen la convención de los archivos normales: rt, wt, xt y at para texto, con equivalentes binarios. Usa creación exclusiva cuando una sobrescritura accidental deba fallar.

Lee sin cargar todo

import lzma

with lzma.open("eventos.log.xz", "rt", encoding="utf-8") as archivo:
    for linea in archivo:
        procesar(linea.rstrip())

La iteración entrega una línea cada vez y combina bien con la guía para leer archivos gigantes con Python. El descompresor mantiene un diccionario interno, por lo que conviene observar la memoria en servicios prolongados.

Usa LZMAFile para binario

LZMAFile acepta una ruta o un archivo ya abierto e implementa gran parte de io.BufferedIOBase. Admite with, iteración, lectura, escritura y búsqueda cuando el recurso lo permite.

from lzma import LZMAFile

with LZMAFile("datos.bin.xz", "wb", preset=5) as destino:
    destino.write(b"cabecera\x00")
    destino.write(b"datos" * 10_000)

Una misma instancia no es segura para lectores o escritores concurrentes. Usa un lock o instancias separadas.

Selecciona el formato

  • FORMAT_XZ: contenedor moderno con checks y filtros.
  • FORMAT_ALONE: formato legado .lzma con menos funciones.
  • FORMAT_RAW: sin contenedor; ambos lados necesitan la cadena exacta.
  • FORMAT_AUTO: detecta XZ o LZMA al descomprimir.

Elige XZ para proyectos nuevos. RAW solo es razonable cuando un protocolo ya define todos los parámetros.

Checks de integridad

XZ puede usar CRC32, CRC64 o SHA-256. CRC64 es el valor predeterminado. Comprueba lzma.is_check_supported() antes de pedir una opción que la liblzma instalada podría no tener.

import lzma

check = lzma.CHECK_SHA256
if not lzma.is_check_supported(check):
    check = lzma.CHECK_CRC64

resultado = lzma.compress(b"contenido", check=check)

Los checks detectan corrupción accidental. No autentican al remitente y no reemplazan una firma o un hash autenticado.

Compresión incremental

import lzma

compresor = lzma.LZMACompressor(preset=6)
partes = []

for bloque in generar_bloques():
    parte = compresor.compress(bloque)
    if parte:
        partes.append(parte)

partes.append(compresor.flush())
comprimido = b"".join(partes)

El objeto puede acumular entrada, por lo que una llamada puede devolver bytes vacíos. flush() termina el stream e impide seguir usando el compresor.

Limita la memoria del descompresor

LZMADecompressor acepta memlimit. Si el stream necesita más memoria, lanza LZMAError. Es una protección importante para entradas externas.

import lzma

dec = lzma.LZMADecompressor(memlimit=128 * 1024 * 1024)
salida = bytearray()
limite_salida = 50 * 1024 * 1024

for bloque in recibir_bloques():
    pendiente = bloque
    while pendiente or not dec.needs_input:
        parte = dec.decompress(pendiente, max_length=64 * 1024)
        pendiente = b""
        salida.extend(parte)
        if len(salida) > limite_salida:
            raise ValueError("la salida excedió el límite")
        if dec.eof:
            break

memlimit controla el espacio de trabajo, no el tamaño final. Combínalo con max_length y un contador total.

Streams concatenados

lzma.decompress() y LZMAFile procesan miembros concatenados. Una sola instancia de LZMADecompressor no. Al llegar a eof, inspecciona unused_data y crea otro descompresor si se permiten más miembros.

Cadenas de filtros

Una cadena admite hasta cuatro filtros y debe terminar con LZMA1 o LZMA2. Delta puede mejorar datos numéricos con cambios regulares; BCJ está pensado para código de máquina.

import lzma

filtros = [
    {"id": lzma.FILTER_DELTA, "dist": 4},
    {"id": lzma.FILTER_LZMA2, "preset": 6},
]
comprimido = lzma.compress(datos, format=lzma.FORMAT_RAW, filters=filtros)

Los filtros personalizados reducen la interoperabilidad. Registra la configuración exacta y prueba todas las implementaciones que deban leerla.

Evita presets extremos

PRESET_EXTREME puede combinarse con niveles de 0 a 9, pero suele aumentar mucho el tiempo por una mejora modesta. No uses 9 extremo dentro de una petición web sin benchmark, límites de memoria y una cola de trabajos controlada.

Seguridad operativa

  • Limita el tamaño comprimido.
  • Usa memlimit y un límite de salida.
  • Comprueba eof para detectar truncamiento.
  • No confíes en extensiones ni nombres suministrados.
  • Almacena en un directorio aislado.
  • Limita el tiempo de CPU.
  • No compartas un descompresor entre hilos.

Si el XZ está dentro de un archivo con rutas, aplica las validaciones del artículo sobre archivos ZIP con Python.

Mide datos reales

Compara tiempo, memoria y tamaño para texto, binarios, multimedia ya comprimida y archivos vacíos. Incluye entradas corruptas, truncadas, múltiples miembros y checks distintos. Prueba presets 3, 6 y 9.

Buenas prácticas

  • Prefiere FORMAT_XZ.
  • Mantén preset 6 hasta medir.
  • Especifica codificación en texto.
  • Usa context managers.
  • Procesa grandes datos por bloques.
  • Finaliza con flush().
  • Combina límites de memoria y salida.
  • Maneja LZMAError sin exponer información sensible.

Conclusión

lzma en Python proporciona compresión XZ eficiente, archivos de texto y binarios, checks y filtros avanzados. Su ventaja principal es el tamaño; sus costes son CPU, memoria y complejidad operativa.

Consulta la documentación oficial de lzma y el proyecto XZ Utils. Para configurar presets y límites, revisa configparser en Python, y para observar memoria usa tracemalloc en Python.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    A laptop screen showing a code editor with visible programming code in a dimly lit environment.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    tarfile en Python: crea TAR seguro

    Aprende tarfile en Python para crear TAR comprimido, inspeccionar miembros y extraer con filtros, límites y protección de rutas.

    Ler mais

    Tempo de leitura: 4 minutos
    17/08/2026
    Row of colorful office binders neatly arranged on a shelf, ideal for organization concepts.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    gzip en Python: comprime archivos .gz

    Aprende gzip en Python para leer y escribir .gz, crear streams reproducibles, procesar datos grandes y limitar la expansión externa.

    Ler mais

    Tempo de leitura: 4 minutos
    17/08/2026
    A close-up shot showcasing the intricate scales of a snake, highlighting texture and color.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    bz2 en Python: comprime con bzip2

    Aprende bz2 en Python para comprimir archivos y bytes, procesar streams por bloques y limitar la expansión de datos externos.

    Ler mais

    Tempo de leitura: 4 minutos
    16/08/2026
    Detailed shot of a Jungle Carpet Python (Morelia spilota cheynei) in its natural habitat.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    zlib en Python: comprime datos

    Aprende zlib en Python para comprimir y descomprimir bytes, procesar streams, usar checksums y limitar datos externos.

    Ler mais

    Tempo de leitura: 6 minutos
    16/08/2026
    Diagrama de archivos y sistema que representa configuración INI con configparser en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    configparser en Python: archivos INI

    Aprende configparser en Python para leer y escribir archivos INI, combinar defaults, usar interpolación y actualizar de forma segura.

    Ler mais

    Tempo de leitura: 5 minutos
    16/08/2026
    Módulo de memoria RAM que representa gestión de objetos con gc en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    gc en Python: controla el recolector

    Aprende gc en Python para controlar la recolección cíclica, inspeccionar objetos, diagnosticar memoria y observar pausas.

    Ler mais

    Tempo de leitura: 7 minutos
    16/08/2026