lzma no Python: comprima arquivos XZ

Publicado em: 17/08/2026
Tempo de leitura: 5 minutos
Color-coded office binders organized neatly in a storage shelf, featuring labels and a striking red binder.

O módulo lzma no Python oferece compressão e descompressão com os algoritmos LZMA e LZMA2. Ele trabalha com arquivos .xz, com o formato legado .lzma e com streams brutos configurados por filtros. A interface inclui funções de uma etapa, objetos incrementais e uma API de arquivo muito parecida com bz2.

LZMA costuma produzir resultados menores que gzip e bzip2 em muitos conjuntos de dados, mas exige mais CPU e pode consumir bastante memória. O preset 9, por exemplo, pode levar o compressor a centenas de megabytes de overhead. Portanto, a escolha deve ser medida com dados reais, e o preset padrão 6 costuma ser um ponto de partida mais seguro.

Quando usar lzma

Use lzma quando o formato XZ for obrigatório, quando tamanho final tiver prioridade e quando o ambiente puder pagar o custo de compressão. Para arquivos que precisam ser abertos rapidamente ou por muitos programas, gzip pode ser mais prático. Para comparar outro algoritmo eficiente em texto, veja bz2 no Python.

Comprima dados em memória

import lzma

dados = ("registro de auditoria\n" * 2000).encode("utf-8")
compactado = lzma.compress(dados, preset=6)
restaurado = lzma.decompress(compactado)

assert restaurado == dados
print(len(dados), len(compactado))

lzma.compress() usa FORMAT_XZ por padrão. A função é conveniente para cargas pequenas, mas mantém entrada e saída em memória. Em volumes grandes, use lzma.open() ou processamento incremental.

Grave arquivos .xz em modo texto

import lzma

with lzma.open("eventos.log.xz", "wt", encoding="utf-8", preset=6) as arquivo:
    arquivo.write("início do processo\n")
    arquivo.write("processamento concluído\n")

Os modos seguem a convenção de open(): rt, wt, xt e at para texto; rb, wb, xb e ab para binário. Use x quando a sobrescrita acidental precisa ser bloqueada.

Leia sem carregar tudo

import lzma

with lzma.open("eventos.log.xz", "rt", encoding="utf-8") as arquivo:
    for linha in arquivo:
        processar(linha.rstrip())

A iteração entrega uma linha por vez e combina bem com as técnicas do guia para ler arquivos gigantes. Mesmo assim, a descompressão mantém estado e dicionário internos; monitore memória em processos longos.

Use LZMAFile quando precisar de binário

LZMAFile aceita um caminho ou um arquivo já aberto. Ele implementa a maior parte de io.BufferedIOBase, suporta with, iteração, leitura, escrita e busca quando o fluxo subjacente permite.

from lzma import LZMAFile

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

Uma única instância não é segura para leitores ou escritores simultâneos. Se várias threads precisarem acessar o mesmo recurso, use um lock ou instâncias independentes.

Escolha o formato correto

  • FORMAT_XZ: formato moderno, com checks de integridade e suporte a filtros.
  • FORMAT_ALONE: formato legado .lzma, mais limitado.
  • FORMAT_RAW: stream sem contêiner; exige a cadeia de filtros na compressão e na descompressão.
  • FORMAT_AUTO: usado para detectar XZ ou LZMA durante a leitura.

Para novos arquivos, prefira XZ. RAW é adequado apenas quando um protocolo externo define todos os parâmetros.

Checks de integridade

O contêiner XZ pode usar CHECK_CRC32, CHECK_CRC64 ou CHECK_SHA256. O padrão é CRC64. Use lzma.is_check_supported() antes de selecionar uma opção que pode não existir na liblzma instalada.

import lzma

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

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

Esses checks detectam corrupção acidental. Eles não substituem assinatura digital, autenticação ou hash protegido contra adulteração.

Compressão incremental

import lzma

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

for bloco in gerar_blocos():
    trecho = compressor.compress(bloco)
    if trecho:
        partes.append(trecho)

partes.append(compressor.flush())
compactado = b"".join(partes)

O objeto pode armazenar dados internamente, portanto uma chamada pode retornar vazio. flush() finaliza o stream e torna o compressor inutilizável.

Limite memória na descompressão

LZMADecompressor aceita memlimit. Se o stream exigir mais memória do que o permitido, a operação falha com LZMAError. Isso é uma proteção importante para conteúdo externo.

import lzma

dec = lzma.LZMADecompressor(memlimit=128 * 1024 * 1024)
saida = bytearray()
limite_saida = 50 * 1024 * 1024

for bloco in receber_blocos():
    pendente = bloco
    while pendente or not dec.needs_input:
        parte = dec.decompress(pendente, max_length=64 * 1024)
        pendente = b""
        saida.extend(parte)
        if len(saida) > limite_saida:
            raise ValueError("saída descompactada excedeu o limite")
        if dec.eof:
            break

memlimit limita a memória do descompressor, mas não limita sozinho o tamanho final. Use também max_length e um contador total.

Streams concatenados

lzma.decompress() e LZMAFile processam múltiplos streams concatenados. Uma instância de LZMADecompressor não faz isso automaticamente. Ao atingir eof, examine unused_data e crie outro objeto se o formato permitir membros adicionais.

Filtros personalizados

Uma cadeia pode ter até quatro filtros, terminando obrigatoriamente em LZMA1 ou LZMA2. O filtro delta pode melhorar dados numéricos com diferenças regulares; filtros BCJ ajudam código de máquina.

import lzma

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

Filtros customizados aumentam a complexidade e prejudicam interoperabilidade. Documente exatamente a cadeia e teste com outras implementações.

Evite presets extremos por padrão

PRESET_EXTREME pode ser combinado com níveis de 0 a 9, mas normalmente aumenta muito o tempo para uma melhoria modesta. Não use 9 extremo em uma API web sem benchmark, limite de memória e fila de trabalho controlada.

Segurança operacional

  • Imponha limite ao arquivo comprimido.
  • Use memlimit e limite total de saída.
  • Valide eof para detectar truncamento.
  • Não confie em extensão ou nome fornecido.
  • Armazene em diretório isolado.
  • Limite tempo de CPU.
  • Não compartilhe a instância entre threads.

Se o XZ vier dentro de um pacote com vários caminhos, aplique também as regras do guia de arquivos ZIP com Python.

Teste com dados representativos

Meça tempo, memória e tamanho com textos, binários, dados já comprimidos e arquivos vazios. Inclua entradas corrompidas, truncadas, vários membros e checks diferentes. Compare presets 3, 6 e 9 antes de decidir.

Boas práticas

  • Prefira FORMAT_XZ em projetos novos.
  • Mantenha o preset padrão até medir.
  • Use modo texto com codificação explícita.
  • Use with para fechar arquivos.
  • Processe grandes volumes incrementalmente.
  • Finalize o compressor com flush().
  • Combine memlimit com limite de saída.
  • Trate LZMAError sem expor dados sensíveis.

Conclusão

O lzma no Python fornece compressão XZ eficiente, arquivos em texto ou binário, checks de integridade e filtros avançados. Sua principal vantagem é a taxa de compressão; seus principais custos são CPU, memória e maior complexidade operacional.

Consulte a documentação oficial do lzma e a página do XZ Utils. Para configurar limites e presets por ambiente, veja configparser no Python.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Rack de servidores representando balanceamento de conexões com SO_REUSEPORT_LB no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    SO_REUSEPORT_LB: distribua conexões entre workers

    Aprenda SO_REUSEPORT_LB no Python para distribuir conexões entre múltiplos workers com segurança, testes e portabilidade.

    Ler mais

    Tempo de leitura: 6 minutos
    11/10/2026
    Código Python assíncrono em notebook para inspect.markcoroutinefunction
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    markcoroutinefunction: identifique wrappers async

    Aprenda inspect.markcoroutinefunction no Python para identificar wrappers assíncronos, integrar frameworks e evitar detecção incorreta de corrotinas.

    Ler mais

    Tempo de leitura: 6 minutos
    10/10/2026
    Código Python para percorrer pastas e arquivos com Path.walk
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    Path.walk: percorra diretórios com segurança

    Aprenda Path.walk no Python para percorrer diretórios, filtrar arquivos, tratar erros e controlar a travessia com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    10/10/2026
    Depuração de processo Python em terminal com código
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pdb -p: depure processos Python em execução

    Aprenda a anexar o pdb a um processo Python em execução, inspecionar pilhas e diagnosticar travamentos com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    09/10/2026
    Código Python e representação de frações numéricas
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    fractions.from_number: converta números em frações

    Aprenda fractions.from_number no Python para converter números em frações exatas, controlar precisão e evitar arredondamentos inesperados.

    Ler mais

    Tempo de leitura: 5 minutos
    09/10/2026
    Desenvolvedor configurando servidor HTTPS e certificado TLS com Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    HTTPSServer: crie servidor HTTPS local no Python

    Aprenda HTTPSServer no Python para servir HTTPS localmente, configurar certificados, usar threads e entender limites de segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    08/10/2026