Introduction
Cet article présente la compression de fichiers avec la librairie Zlib de Jean-loup Gailly et Mark Adler.
Les fichiers compressés avec cet algorithme portent l'extention gz.
La librairie est téléchargeable ici :
http://www.gzip.org/zlib/
Accès aux fichiers
Pour enregistrer ou lire un fichier compressé, il faut utiliser les fonctions gzopen() et gzclose()
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.
Ouverture
Les modes d'ouverture des fichiers sont les mêmes qu'avec la fonction standard fopen().
| Mode | Description |
r | ouverture en lecture seule, pointeur placé en début de fichier |
r+ | ouverture en lecture et écriture, pointeur placé en début de fichier |
w | ouverture en écriture seule, pointeur placé en début de fichier, écrase le contenu du fichier, si le fichier n'existe pas, on tente de le créer |
w+ | ouverture en lecture et écriture, pointeur placé en début de fichier, écrase le contenu du fichier, si le fichier n'existe pas, on tente de le créer |
a | ouverture en lecture seule, pointeur placé en fin de fichier, si le fichier n'existe pas, on tente de le créer |
a+ | ouverture en lecture et écriture, pointeur placé en fin de fichier, si le fichier n'existe pas, on tente de le créer |
Ce mode peut être complété par le niveau de compression (en écriture seulement) entier compris entre 0 et 9,
exemple : w5.
Un autre suffixe peut être ajouté pour indiquer une heuristique pour filtrer les données : f, exemple :
w5f.
Le suffixe h permet de n'activer que la compression de Huffman, exemple : w5h.
Syntaxe d'ouverture de fichier :
resource gzopen(string $filename, string $mode, int $use_include_path)
Exemple d'ouverture de fichier en lecture :
$gz = gzopen("archive.gz", "r");
Si le paramètre optionnel $use_include_path est passé à 1, alors la fonction gzopen()
recherchera le fichier dans le répertoire défini par la directive de configuration include_path du php.ini.
La fonction gzopen() retourne un entier valant false en cas d'erreur.
Fermeture
Syntaxe de fermeture de fichier :
int gzclose(resource $gz)
Exemple de fermeture de fichier :
gzclose($gz);
La fonction gzclose() retourne un entier valant true si succès, ou false en cas d'erreur.
Accès aux données
Les accès au contenu des fichiers ouverts dépendent de leur mode d'ouverture.
On peut lire avec gzread() un fichier ouvert en lecture,
et écrire avec gzwrite() dans un fichier ouvert en écriture.
Lecture
Par bloc
Syntaxe :
string gzread(resource $gz, int $length)
Exemples :
$str = gzread($gz, 1024);
La fonction gzread() 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 en fin de fichier si celle-ci à été atteinte.
Par ligne
Syntaxe :
string gzgets(resource $gz, int $length)
Retourne une chaîne décompressée de taille maximale $length - 1. La lecture s'arrête si un saut de ligne
ou une fin de fichier est rencontré(e). Permet une lecture ligne par ligne du fichier.
Par ligne, sans balise
Syntaxe :
string gzgetss(resource $gz, int $length [, string $allowable_tags ])
Identique à gzgets(), sauf que toutes les balises HTML et PHP sont automatiquement supprimées.
Le paramètre optionnel $allowable_tags permet de lister les balises à conserver.
Par catactère
Syntaxe :
string gzgetc(resource $gz)
Retourne une chaîne décompressée contenant un seul caractère. Permet une lecture caractère par caractère du fichier.
Retourne false si la fin du fichier est atteinte.
Tout le fichier dans un tableau
Syntaxe :
array gzfile(string $filename [, int $use_include_path ])
Exemple :
$file = gzfile('archive.gz');
foreach($file as $elem) {
$text .= trim($elem);
}
Identique à la fonction file() mais décompresse à la volée le contenu du fichier, si celui-ci est compressé
(cette fonction peut donc servir à lire des fichiers non compressés).
Retourne un tableau dont chaque élément est une ligne du fichier $filename.
Le paramètre optionnel $use_include_path passé à 1 permet de rechercher
le fichier dans le répertoire défini par la directive de configuration include_path du php.ini.
Attention : contrairement aux autres fonctions, cette fonction prend pour paramètre
le nom du fichier et pas un pointeur créé par gzopen(). Il n'est donc pas utile d'ouvrir le fichier au préalable.
Tout le fichier à l'écran
Syntaxe :
int readgzfile(string $filename [, int $use_include_path ])
Exemple :
readgzfile('archive.gz');
Identique à la fonction readfile() mais décompresse à la volée le contenu du fichier, si celui-ci est compressé
(cette fonction peut donc servir à lire des fichiers non compressés).
Lit le fichier et l'affiche directement dans la sortie standard.
Retourne le nombre d'octets décompressés.
Le paramètre optionnel $use_include_path passé à 1 permet de rechercher
le fichier dans le répertoire défini par la directive de configuration include_path du php.ini.
Attention : contrairement aux autres fonctions, cette fonction prend pour paramètre
le nom du fichier et pas un pointeur créé par gzopen(). Il n'est donc pas utile d'ouvrir le fichier au préalable.
Ecriture
Syntaxe d'écriture :
int gzwrite(resource $gz, string $str [, int $length ])
Exemples d'écriture :
gzwrite($gz, $str);
gzwrite($gz, $str, 1024);
La fonction gzwrite() 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.
gzputs() est un alias de gzwrite()
Position du pointeur interne
Position du pointeur
Syntaxe :
int gztell(resource $gz)
Identique à ftell() : retourne la position courante du pointeur de lecture dans le fichier.
Déplacement du pointeur
Syntaxe :
int gzseek(resource $gz, int $offset)
Semblable à fseek().
Déplace de $offset octets dans le fichier.
S'il est ouvert en écriture, seuls les déplacements vers l'avant sont possibles : il compresse une série de zéros
jusqu'à la position indiquée. Retourne 0 si succès, -1 sinon.
Retour au début
Syntaxe :
int gzrewind(resource $gz)
Identique à rewind().
Replace le pointeur interne au début du fichier.
Utile pour relire un fichier.
Retourne 0 en cas d'échec.
Fin de fichier
Syntaxe :
int gzeof(resource $gz)
Identique à feof().
Retourne true si la fin du fichier a été atteinte, false sinon.
Compression à la volée
Compression
Syntaxe de compression :
string gzcompress(string $str [, int $level ])
Exemples de compression :
$str = gzcompress($str, 9);
$str = gzcompress($str);
La fonction gzcompress() compresse la chaîne $str et retourne le résultat.
L'argument optionel $level définit la qualité de la compression, ce doit être un nombre entier positif compris
entre 0 (pas de compression) et 9 (compression maximale).
Attention : cette fonction ne doit pas être utilisée pour créer un fichier archive car ce dernier
doit comporter des entêtes que seules les fonctions gzencode() et gzopen() créent.
Décompression
Syntaxe de décompression :
string gzuncompress(string $str [, int $length])
Exemples de décompression :
$str = gzuncompress($str, 100);
$str = gzuncompress($str);
La fonction gzuncompress() décompresse la chaîne $str compressée par gzcompress()
et retourne le résultat. Cette fonction retourne false si la chaîne décompressée est plus de 256 fois supérieure
à la chaîne compressée $str, ou de taille supérieure à $length caractères.
Compression indépendante
Syntaxe :
string gzencode(string $data [, int $level [, int $encoding_mode ] ])
Exemple :
$data = implode('', file('test.txt'));
$gzdata = gzencode($data, 9);
$fp = fopen('test.txt.gz', 'w');
fwrite($fp, $gzdata);
fclose($fp);
Retourne une chaîne résultant de la compression de $data ou false si échec.
Le paramètre optionnel $level spécifie le niveau de compression (entre 0 et 9).
Le paramètre optionnel $encoding_mode permet de spécifier la constante FORCE_GZIP (par défaut)
ou bien FORCE_DEFLATE, cette dernière produit une chaîne compressée réduite sans la somme de contrôle finale CRC32.
Contrairement à gzcompress(), cette fonction produit tous les entêtes nécessaires à la création d'un fichier
avec les fonctions standards.
Exemples
Compression d'un fichier du serveur
Le script ci-dessous procède comme suit :
- lecture du fichier source avec les fonctions standards
fopen() et fread(),
- compression du contenu de ce fichier avec
gzencode(),
- création d'un nouveau fichier avec les fonctions standards, dont le contenu est le résultat de la compression
du premier fichier,
- affichage à l'écran du grain de la compression en valeur absolue et en valeur relative.
<?php /****************************************** * COMPRESSION D'UN FICHIER DU SERVEUR * * - lecture des données originales * - compression avec gzencode() * - écriture des données compressées * - affichage du gain de la compression * * 29 mai 2003, Hugo ETIEVANT * http://cyberzoide.developpez.com/php4/ *******************************************/
// nom et chemin du fichier à compresser $filename = './gz.pdf';
// ouverture du fichier à compresser if($fp = fopen($filename, "rb")) {
// lecture du contenu $size1 = filesize($filename); $data = fread($fp, $size1); // fermeture fclose($fp); // compression des données $gzdata = gzencode($data, 9); // ouverture et création du fichier compressé if($fp = fopen($filename.'.gz', 'wb')) {
// écriture des données compressées fwrite($fp, $gzdata); // fermeture fclose($fp); // calcul gain de la compression $size2 = filesize($filename.'.gz'); $diff = $size1-$size2; $pc = round($diff/$size1*100, 2); echo "Gain de la compression : $diff octets soit $pc %.";
} else { echo "Impossible d'ouvrir $filename.gz en écriture."; }
} else { echo "Impossible d'ouvrir $filename en lecture."; }
?>
Affiche ceci :
Gain de la compression : 17909 octets soit 32.63 %.
Affichage du contenu d'un fichier compressé
Le script ci-dessous procède comme suit :
- ouverture d'un fichier compressé avec
gzopen() en mode lecture binaire ("rb"),
- lecture et décompression à la volée du contenu par bloc de 1024 avec
gzread()
tant que la fin de fichier n'est pas vérifiée (gzeof()),
- affichage du texte à l'écran.
<?php /****************************************** * LECTURE D'UN FICHIER COMPRESSE * * 29 mai 2003, Hugo ETIEVANT * http://cyberzoide.developpez.com/php4/ *******************************************/
// nom et chemin du fichier compressé $filename = './gz.txt.gz';
// ouverture du fichier compresser à lire if($gz = gzopen($filename, "rb")) {
// tant qu'on n'a pas atteint la fin du fichier while(!gzeof($gz)) { // lecture et décompression à la volée $text.= gzread($gz, 1024); } // affichage du texte echo $text; } else { echo "Impossible d'ouvrir $filename en lecture."; }
?>
Je remercie Le vieux
pour la relecture et ses suggestions de corrections orthographiques.
|