La lecture et l'écriture des fichiers compressés aux formats ZIP ou GZIP sont directement gérées par des classes adaptées fournies dans l'API Java. En effet, il suffit d'utiliser les classes appropriées se trouvant dans le paquetage java.util.zip.

import java.util.zip.*;

Pour la compression, on distingue la classe DeflaterOutputStream comprenant également deux sous-classes GZIPOutputStream et ZipOutputStream se chargeant de compresser les données transitant dans le flux, dans un format GZIP et ZIP.

import java.util.zip.*;
import java.io.*;
public class ZIP {
  public static void main(String args[]) throws Exception {
   //Déclaration de l'archive ZIP
   String repertoire = "c:java";
   String archive = "arc.zip";
   File fic = new File(repertoire, archive);
   FileOutputStream flux = new FileOutputStream(fic);
   ZipOutputStream ficZIP = new ZipOutputStream(flux);
   //Méthode de compression DEFLATED ou STORED
   ficZIP.setMethod(ZipOutputStream.DEFLATED);
   //Niveau de compression
   //de 1 (NO_COMPRESSION) à 9 (BEST_COMPRESSION)
   ficZIP.setLevel(Deflater.BEST_COMPRESSION);
   //Déclaration de la première entrée de l'archive
   String entreeFichier = "fichier.txt";
   ZipEntry entreeZIP = new ZipEntry(entreeFichier);
   ficZIP.putNextEntry(entreeZIP);
   //Envoie du contenu de la premiere entrée 
   //dans l'archive à travers un flux
   BufferedOutputStream tamponSortie = 
                                         new BufferedOutputStream(ficZIP);
   DataOutputStream ficDonnees = 
                                         new DataOutputStream(tamponSortie);
   ficDonnees.writeBytes("Un contenu à archiver !");
   ficDonnees.flush();
   //Fermeture de l'archive jusqu'à la prochaîne entrée
   ficZIP.closeEntry();
   System.out.println ("Taille 1ere entree : " 
                                                 + entreeZIP.getCompressedSize());
   //Déclaration de la seconde entrée de l'archive
   String entreeFichier2 = "poeme.rtf";
   ZipEntry entreeZIP2 = new ZipEntry(entreeFichier2);
   ficZIP.putNextEntry(entreeZIP2);
   BufferedOutputStream tamponSortie2 = 
                                        new BufferedOutputStream(ficZIP);
   DataOutputStream ficDonnees2 = 
                                        new DataOutputStream(tamponSortie2);
   ficDonnees2.writeBytes("Un second contenu à archiver !");
   ficDonnees2.flush();
   //Fermeture de l'entrée
   ficZIP.closeEntry();
   System.out.println ("Taille Snde entree : " 
                                                 + entreeZIP2.getCompressedSize());
   //Fermeture de l'archive et des flux
   ficZIP.close();
   ficDonnees.close();
   ficDonnees2.close();
   flux.flush();
   flux.close();
  }
}

Les archives compressées contiennent en général un à plusieurs fichiers. En Java, ces derniers sont représentés par des objets de type référence ZipEntry. Ainsi, à chaque archive ZIP ou GZIP doit être associée au moins une entrée dans laquelle devra être le conteneur de données compressées.

//Création d'un nouvelle entrée
ZipEntry entreeZIP = new ZipEntry(nomFichier);
//Récupération d'une entrée existante
ZipEntry entreeZIP = objZipInputStream.getNextEntry();

L'écriture des données dans l'archive est en général assurée par un objet DataOutputStream qui possède un arsenal de méthodes write() acceptant tous les types primitifs Java, ainsi que les chaînes de caractères.

En ce qui concerne la décompression, on trouve la classe InflaterInputStream possédant deux sous-classes GZIPInputStream et ZipInputStream constituant des filtres de flux pour la lecture de données compressées dans le format GZIP et ZIP.

import java.util.zip.*;
import java.io.*;
public class ZIP {
  public static void main(String args[]) throws Exception {
   //Déclaration de l'archive ZIP
   String repertoire = "c:java";
   String archive = "arc.zip";
   File fic = new File(repertoire, archive);
   FileInputStream flux = new FileInputStream(fic);
   ZipInputStream ficZIP = new ZipInputStream(flux);
   //Récupération de la première entrée
   ZipEntry entreeZIP = ficZIP.getNextEntry();
   BufferedInputStream tamponSortie = 
                                       new BufferedInputStream(ficZIP);
   DataInputStream ficDonnees = 
                                       new DataInputStream(tamponSortie);
   int car;
   System.out.println ("Archive ZIP : " + entreeZIP.getName());
   while((car = ficDonnees.read()) != -1)
       System.out.print ((char) car);
   //Fermeture de l'archive jusqu'à la prochaîne entrée
   ficZIP.closeEntry();
   System.out.println ("");
   //Récupération de la seconde entrée
   ZipEntry entreeZIP2 = ficZIP.getNextEntry();
   BufferedInputStream tamponSortie2 = 
                                         new BufferedInputStream(ficZIP);
   DataInputStream ficDonnees2 = 
                                         new DataInputStream(tamponSortie2);
   System.out.println ("Archive ZIP : " + entreeZIP2.getName());
   while((car = ficDonnees2.read()) != -1)
       System.out.print ((char) car);
   //Fermeture de l'archive
   ficZIP.close();
   ficDonnees.close();
   ficDonnees2.close();
   flux.close();
  }
}

L'objet ZipEntry possède des méthodes capables de fournir des informations sur le fichier compressé.

Méthodes Description
getComments() retourne le commentaire additionnel affecté à l'entrée.
getCompressedSize() retourne la taille du fichier compressé, exprimée en octets.
getMethod() retourne la méthode de compression du fichier (DEFLATED : compression, STORED : sans compression).
getName() retourne le nom associé à l'entrée, soit en général le nom du fichier.
getSize() retourne la taille du fichier non-compressé, exprimé en octets.
getTime() retourne la date (Date + heure) du fichier, exprimé sous la forme d'un entier long.

Les fichiers compressés à l'aide des outils proposés par le paquetage java.util, sont normalement compatibles avec les logiciels de décompression courant. Néanmoins, il arrive parfois qu'avec d'anciennes versions de ces logiciels, la décompression soit impossible.

Télécharger l'ensemble des exemples