XD blog

blog page

bz2, compression, python


2013-09-27 Format de compression BZ2

Il existe beaucoup de formats de compression. Le plus connu est dans doute le format zip. Il serait impossible de tous les citer (voir compression). Un des logiciels les plus utilisés sous Windows est 7z. Il permet de compresser / décompresser les formats les plus utilisés pour la compression du texte. Et le format 7-zip est le plus souvent le plus efficace.

Alors pourquoi aurait-on besoin d'autre format de compression ? Ce qui marche pour le texte ne marche pas forcément très bien sur la musique, les images ou la vidéo. Pour le texte, on cherche toujours une compression sans erreur. On accepterait mal qu'un document se retrouve altéré durant les étapes de compression / décompression. Pour les images, on recherche principalement des compressions avec un peu de perte : une déterioration de la qualité de l'image qui soit presque invisible pour l'oeil humain. Le format MP3 est aussi une compression de la musique avec perte. Pour la vidéo qui est très gourmande, on utilise le fait que les images changent peu d'une seconde à l'autre comme le décor en fond d'écran. On ne va donc pas compresser les images directement mais la différence entre une image et sa précédente.

Pour en revenir aux données qu'on compresse sans perte, pourquoi utiliser un autre format de compression si 7-zip est meilleur ? En fait, il est meilleur la plupart du temps mais pour certains usages précis, d'autres formats sont plus adaptés, plus simples ou plus performants. Le format Bzip2 ou Bz2. Pour citer Wikipedia, les avantages de ce format sont : une faible utilisation mémoire à la compression, la robustesse des archives à la corruption et la parallélisation possible sur de nombreux threads.

Pour compresser du texte en Python au format bz2, on utilise le programme suivant :

import bz2

# les lignes de texte à décompresser
lines = ["line1", "line2 é"]

# on ouvre un fichier classique en mode binaire
with open(file,"wb") as f :
    comp = bz2.BZ2Compressor()
    for line in lines :
        tof = line + "\n"  # on ajoute une fin de ligne
                           # puis on encode en utf8 avant de compresser
        c = comp.compress ( tof.encode("utf8")  )
        f.write( c )
    c = comp.flush()   # il ne faut pas oublier car le 
    f.write( c )       # BZ2Compressor fonctionne comme un buffer

Pour le relire :

import bz2
lines = [ ]
with bz2.BZ2File(file, "r") as f :
    for line in f :
        s = str(line, encoding = "utf8")
        lines.append (s)
Avec ses deux exemples, il n'est pas besoin de conserver une version décompressée du fichier. On écrit et lit directement les données au format compressé.


<-- -->

Xavier Dupré