I. Introduction

Ce tutoriel présente la compression de fichiers avec la bibliothèque bzip2 de Julian Seward. Les fichiers compressés avec cet algorithme portent l'extension bz2. La bibliothèque bzip2/libbzip2 est téléchargeable ici : http://sources.redhat.com/bzip2/.

II. Accès aux fichiers

Pour enregistrer ou lire un fichier compressé, il faut utiliser les fonctions bzopen() et bzclose() sur le même modèle que les fonctions standards fopen() et fclose(). Ces deux fonctions retournent un pointeur de fichier qui devra être passé en argument aux autres fonctions de traitement. Il existe deux modes d'ouverture de fichier : en lecture « r » en écriture « w ».

II-A. Ouverture

Syntaxe d'ouverture de fichier :

 
Sélectionnez
1.
resource bzopen(string $filename, string $mode)

Exemple d'ouverture de fichier en lecture :

 
Sélectionnez
1.
$bz = bzopen("archive.bz2", "r");

La fonction bzopen() retourne un entier valant false en cas d'erreur.

II-B. Fermeture

Syntaxe de fermeture de fichier :

 
Sélectionnez
1.
int bzclose(resource $bz)

Exemple de fermeture de fichier :

 
Sélectionnez
1.
bzclose($bz);

La fonction bzclose() retourne un entier valant true si succès, ou false en cas d'erreur.

III. Accès aux données

Les accès au contenu des fichiers ouverts dépendent de leur mode d'ouverture. On peut lire avec bzread() un fichier ouvert en lecture, et écrire avec bzwrite() dans un fichier ouvert en écriture.

III-A. Lecture

Syntaxe de lecture :

 
Sélectionnez
1.
string bzread(resource $bz [, int $length ])

Exemples de lecture :

 
Sélectionnez
1.
2.
$str = bzread($bz);
$str = bzread($bz, 10);

La fonction bzread() retourne une chaîne de caractères en décompressant à la volée le fichier spécifié. La lecture commence à la position courante et se termine après $length caractères décompressés lus, ou dès que survient une erreur, ou après 1024 caractères décompressés lus, ou en fin de fichier si celle-ci a été atteinte.

III-B. Écriture

Syntaxe d'écriture :

 
Sélectionnez
1.
int bzwrite(resource $bz, string $str [, int $length ])

Exemples d'écriture :

 
Sélectionnez
1.
2.
bzwrite($bz, $str);
bzwrite($bz, $str, 10);

La fonction bzwrite() compresse la chaîne $str à la volée et écrit le résultat dans le fichier spécifié. L'écriture débute à la position courante du fichier et s'arrête après $length caractères non compressés écrits ou dès que la fin de la chaîne $str a été atteinte.

III-C. Tampons d'écriture

Syntaxe de vidage des tampons :

 
Sélectionnez
1.
int bzflush(resource $bz)

Exemple :

 
Sélectionnez
1.
bzflush($bz);

La fonction bzflush() vide les tampons d'écriture sur le fichier ouvert en écriture. Comme pour la bibliothèque standard, les données ne sont pas écrites directement dans le fichier, mais par blocs. Quand un bloc en mémoire est plein, il est transféré sur le disque. Quand le fichier s'apprête à être fermé, les blocs qui restent (non pleins) sont eux aussi transférés sur disque.

III-D. Gestion des erreurs

Syntaxe d'obtention de la dernière erreur :

 
Sélectionnez
1.
array bzerror(resource $bz)

Exemple :

 
Sélectionnez
1.
2.
3.
$error = bzerror($bz);
echo $error["errno"];
echo $error["errstr"];

La fonction bzerror() retourne un tableau associatif ayant pour clés : « errno » et « errstr » auxquelles sont associées respectivement les valeurs suivantes : le dernier code d'erreur généré par les fonctions Bz sur le fichier identifié par le pointeur $bz, et la description (en anglais) de ce code erreur.

D'autres fonctions sont disponibles : bzerrno() et bzerrstr() qui retournent respectivement le numéro et la description du dernier code d'erreur généré sur le fichier spécifié.

Syntaxes :

 
Sélectionnez
1.
2.
int bzerrno(resource $bz)
string bzerrstr(resource $bz)

Exemple :

 
Sélectionnez
1.
echo "Dernière erreur : ".bzerrno($bz)." : ".bzerrstr($bz);

IV. Compression à la volée

IV-A. Compression

Syntaxe de compression :

 
Sélectionnez
1.
string bzcompress(string $str [, int $blocksize [, int $workfactor]])

Exemples de compression :

 
Sélectionnez
1.
2.
3.
$str = bzcompress($str, 9, 100);
$str = bzcompress($str, 9);
$str = bzcompress($str);

La fonction bzcompress compresse la chaîne $str et retourne le résultat. L'argument optionnel $blocksize définit la qualité de la compression, ce doit être un nombre entier positif compris entre 1 et 9. Sa valeur par défaut est 4. Il représente la taille des blocs de données utilisés lors de la compression. L'argument $workfactor est un nombre entier compris entre 0 et 250, sa valeur par défaut est 30. Il permet d'orienter le comportement de l'algorithme de compression dans le cas où la chaîne à compresser comporte des motifs exagérément répétés.

IV-B. Décompression

Syntaxe de décompression :

 
Sélectionnez
1.
string bzdecompress(string $str [, int $small])

Exemples de décompression :

 
Sélectionnez
1.
2.
$str = bzdecompress($str, true);
$str = bzdecompress($str);

La fonction bzdecompress décompresse la chaîne $str et retourne le résultat. Si le paramètre optionnel $small est passé à true, alors un autre algorithme moins gourmand en mémoire (mais moins rapide) sera utilisé.

V. Téléchargement de fichier compressé

Vous souhaitez permettre aux internautes de télécharger un fichier compressé. Pour cela vous disposez des deux méthodes suivantes.

V-A. Compression à la volée

En compressant à la volée le contenu d'un fichier quelconque.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
<?php
  // nom du fichier à compresser
  $filename = 'test.txt';
  // entêtes HTTP
  header('Content-Type: application/x-bzip');
  header('Content-Disposition: attachment; filename='.$filename);
  // extraction du contenu du fichier
  $fp = fopen ($filename, 'r');
  $file = fread($fp, filesize($filename));
  fclose ($fp);
  // compression et affichage
  echo bzcompress($file);
?>

V-B. Compression d'un fichier

En créant un nouveau fichier.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
<?php
  // nom du fichier à créer
  $filename = 'test.bz2';
  // contenu à compresser
  $str = 'Chaîne à compresser.';
  // entêtes HTTP
  header('Content-Type: application/x-bzip');
  // force le téléchargement
  header('Content-Disposition: attachment; filename='.$filename);
  // création du fichier
  $bz = bzopen($filename, "w");
  // écriture
  bzwrite($bz, $str);
  // fermeture
  bzclose($bz);
  // affichage du contenu compressé du fichier
  readfile($filename);
?>

Je remercie Le vieux pour la relecture et ses suggestions de corrections orthographiques.