La classe zip4j
Zipper un fichier
Vous pouvez télécharger la librairie sur Zip4J.
Il suffit de créer un répertoire dans votre projet (par exemple lib) et de copier le jar précédemment téléchargé dans ce répertoire.
Enfin, ajouter dans votre projet cette librairie...
Menu project/properties dans java built path, onglet librairies, add jars et sélectionnez le jar zip4j.
Définir les paramètres d'un fichier zip
Avant de zipper un fichier, il faut définir des paramètres. Ces paramètres seront renseignés via la classe ZipParameters qu'il faudra instancier.
ZipParameters zipParameters = new ZipParameters();
Méthode de compression
Il sera possible de préciser la méthode de compression en utilisant la méthode setCompressionMethod:
Trois valeurs sont possibles: Zip4jConstants.COMP_STORED pour stocker un fichier sans le compresser, Zip4jConstants.COMP_DEFLATE pour compresser un fichier ou encore Zip4jConstants.COMP_AES_ENC.
zipParameters.setCompressionMethod (Zip4jConstants.COMP_DEFLATE);
Taux de compression
Il s'agit d'indiquer le taux de compression. Plus le taux est élevé, plus le fichier a des chances d'être fortement compressé, mais plus il faudra de temps au système pour faire cette compression.
La méthode à utiliser sera setCompressionLevel () suivi d'une valeur:
Ces valeurs existent sous forme de constantes et sont définies dans la classe Zip4jConstants:
DEFLATE_LEVEL_FAST, DEFLATE_LEVEL_FASTEST, DEFLATE_LEVEL_NORMAL, DEFLATE_LEVEL_MAXIMUM ou DEFLATE_LEVEL_ULTRA
Exemple:
zipParameters.setLevel(Deflater.BEST_COMPRESSION);
Cryptage des données
La méthode setEncryptFiles() attend un booleen : true pour crypter, false pour normal.
Dans le cas d'un cryptage de fichier, il faudra préciser la méthode de cryptage:
setEncryptionMethod() qui attend le mode. Mode pour lequel il existe des constantes:
Zip4jConstants.ENC_METHOD_AES, ENC_METHOD_NORMAL ou ENC_METHOD_NO_ENCRYPTION
Il sera possible de préciser la longueur de la clef AES avec la méthode setAesKeyStrength() qui peut recevoir:
Zip4jConstants.AES_STRENGTH_128, Zip4jConstants.AES_STRENGTH_192 ou Zip4jConstants.AES_STRENGTH_256
Enfin, il faut fournir le mot de passe qui sera utilisé pour décrypter le fichier:
zipParameters.setPassword("Mot_de_passe"); où mot_de_passe est le mot de passe que vous aurez choisi...
Phase de compression
Plusieurs solutions sont possibles:
- Tous les fichiers à zipper sont présents dans un répertoire
et vous voulez conserver l'arborescence:
Plutôt que de réinventer la roue (parcourir une arborescence, ...), utilisez la classe ZipFile qui fera tout pour vous. Vous passez au constructeur le nom de l'archive ou une instance de File ZipFile (String path) ou ZipFile (File file).
Dans cette classe est présente la méthode addFolder() qui se décline en addFolder(String path, ZipParameters zipParameters) ou addFolder(File file, ZipParameters zipParameters).
- Vous voulez ajouter un ou quelques fichiers et tout en conservant l'arborescence:
De nouveau, l'utilisation de la classe ZipFile est conseillée...
Utilisez la méthode addFile (File file, ZipParameters zipParameters) (Voir exemple ci-dessous...)
ou addFiles (ArrayList sourceFileList, ZipParameters zipParameters) (addFiles avec un S)
Exemple avec conservation de l'arborescence
Dézipper un/des fichiers
La première chose à faire, sera de vérifier que l'archive est cryptée ou non. Si celle-ci est cryptée, alors fournir le mot de passe qui va permettre de décrypter les fichiers.
Il existe plusieurs solutions pour extraire les fichiers, mais les méthodes pour vérifier la présence d'un cryptage et passer un mot de passe sont identiques: isEncrypted() pour contrôler la présence d'un cryptage et si le résultat est positif, alors utilisation d'une méthode déjà vu: setPassword("Mot_de_passe"); où mot_de_passe est le mot de passe pour décrypter les fichiers...
- Cas 1, vous voulez extraire l'ensemble des fichiers (en conservant l'arborescence d'origine) vers un répertoire destination:
Vous utilisez la classe ZipFile qui fera encore tout pour vous. Vous passez au constructeur le nom de l'archive ou une instance de File ZipFile (String path) ou ZipFile (File file).
Vous contrôler que le fichier zip est crypté ou non et vous passez éventuellement le mot de passe.
Puis vous utilisez la méthode extractAll(String destination) en indiquant dans destination le répertoire destination (qui peut être dans une arborescence complexe).
Le répertoire
destination peut ne pas exister. Lors de l'extraction, le (les) répertoire(s)
seront générés.
Voir exemple de dézippe de l'ensemble des fichiers/répertoires d'une archive ci-dessous.
- Cas 2, extraire certains fichiers vers un répertoire destination tout en conservant une arborescence, en nommant éventuellement le fichier destination:
Il faut toujours utiliser la classe ZipFile, la méthode sera extractFile() qui se décline en :
extractFile (String fichier, String Destination)
fichier sera obligatoirement relatif (par exemple si à l'origine vous aviez c:\toto\tutu\monfic.txt, le fichier à extraire sera toto\tutu\monfic.txt.
extractFile (String fichier, String Destination, UnzipParameters) identique à ci-dessus, mais il sera possible de demander lors de l'extraction à conserver ou non la date d'origine, les attributs du fichier archivé, ...
extractFile (String fichier, String Destination, UnzipParameters unZipParameters, ) identique à ci-dessus, mais il sera possible de demander lors de l'extraction à conserver ou non la date d'origine, les attributs du fichier archivé, ...
unZipParameters pourra être null.
extractFile (String fichier, String Destination, UnzipParameters unZipParameters, String fileDestination) identique à ci-dessus, en précisant fileDestination qui sera un répertoire chemin/fichier autre que celui d'origine(paramètre fichier).
là aussi, le chemin sera relatif, puisque ajouté à celui de destination indiqué en second paramètre de la méthode.
Exemple de dézippe de l'ensemble des fichiers/répertoires d'une archive
UnZipParameters
Entre aperçu lors de l'extraction d'une archive d'un fichier Zip, cette classe permet d'indiquer quoi faire des différents attributs d'un fichier (faut-il les appliquer ou non au nouveau fichier extrait ?).
Donc d'abort instancier la classe:
UnzipParameters unZipParameters=new UnzipParameters();
Puis positionner les valeurs à vrai pour ignorer:
setIgnoreArchiveFileAttribute(boolean ignoreArchiveFileAttribute): Pour ignorer l'attribut "archive" d'un fichier.
setIgnoreDateTimeAttributes(boolean ignoreDateTimeAttributes): Pour ne pas repositionner la date et heure qui se trouvait sur le fichier d'origine.
setIgnoreHiddenFileAttribute(boolean ignoreHiddenFileAttribute): Pour ne pas repositionner l'attribut "caché".
setIgnoreReadOnlyFileAttribute(boolean ignoreReadOnlyFileAttribute): Pour ignorer l'attribut "lecture seul".
setIgnoreSystemFileAttribute(boolean ignoreSystemFileAttribute): Pour ignorer l'attribut "systeme".
setIgnoreAllFileAttributes(boolean ignoreAllFileAttributes): Pour ignorer tous les attributs précédents...
Tous ces attributs ignores pourront être revérifiés plus tard via les méthodes isIgnorexxxxxx... comme isIgnoreArchiveFileAttribute().
Lister les entrées
Comme dans la classe Zip standard, Chaque fichier est enregistré sous forme d'entrée nommé ici FileHeader. Il est possible de récupérer la liste de ces entrées, de connaître le nom, taille, ...La classe net.lingala.zip4j.model.FileHeader va permettre de gérer tout cela. Pour récupérer la liste des entrées, il suffit d'utiliser ZipFile:
List fileHeaderList = zipFile.getFileHeaders();
Maintenant que vous avez cette liste, vous pouvez récupérer les informations de ces entrées:
fileHeader.getFileName() pour le nom
fileHeader.getUncompressedSize pour la taille du fichier décompressé.
et encore d'autres informations...(crc, version, ...)
Hacking ZIP
Rien n'empêchera d'utiliser une méthode "brute force" pour tenter de trouver un mot de passe perdu d'un fichier zip...Mais là, c'est autre chose.