J’ai regardé la bibliothèque Zip par défaut fournie avec les librairies de compression JDK et Apache et je ne suis pas satisfaite pour trois raisons:
Ils sont gonflés et mal conçus. Je dois écrire 50 lignes de sortie de tableau d’octets de plaque chauffante, une entrée zip, créer des stream de fichiers et fermer les stream pertinents et intercepter les exceptions et déplacer les tampons d’octets par moi-même ? Pourquoi je ne peux pas avoir une simple API qui ressemble à ce Zipper.unzip(InputStream zipFile, File targetDirectory, Ssortingng password = null)
et Zipper.zip(File targetDirectory, Ssortingng password = null)
qui ne fonctionne que?
Il semble que la décompression entraîne la destruction des métadonnées de fichiers et que la gestion des mots de passe est rompue.
En outre, toutes les bibliothèques que j’ai essayées étaient 2 à 3 fois plus lentes que les outils zip de la ligne de commande fournis avec UNIX?
Pour moi (2) et (3) sont des points mineurs mais je veux vraiment une bonne bibliothèque testée avec une interface à une ligne.
Je sais que c’est tard et qu’il y a beaucoup de réponses, mais ce zip4j est l’une des meilleures bibliothèques pour compresser que j’ai utilisées. C’est simple (pas de code de chaudière) et peut facilement gérer les fichiers protégés par mot de passe.
import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.core.ZipFile; public static void unzip(){ Ssortingng source = "some/compressed/file.zip"; Ssortingng destination = "some/destination/folder"; Ssortingng password = "password"; try { ZipFile zipFile = new ZipFile(source); if (zipFile.isEncrypted()) { zipFile.setPassword(password); } zipFile.extractAll(destination); } catch (ZipException e) { e.printStackTrace(); } }
La dépendance de Maven est:
net.lingala.zip4j zip4j 1.3.2
Avec Apache Commons-IO ‘s IOUtils
vous pouvez faire ceci:
java.util.zip.ZipFile zipFile = new ZipFile(file); try { Enumeration extends ZipEntry> ensortinges = zipFile.ensortinges(); while (ensortinges.hasMoreElements()) { ZipEntry entry = ensortinges.nextElement(); File entryDestination = new File(outputDir, entry.getName()); if (entry.isDirectory()) { entryDestination.mkdirs(); } else { entryDestination.getParentFile().mkdirs(); InputStream in = zipFile.getInputStream(entry); OutputStream out = new FileOutputStream(entryDestination); IOUtils.copy(in, out); IOUtils.closeQuietly(in); out.close(); } } } finally { zipFile.close(); }
C’est encore du code standard, mais il n’y a qu’une dépendance non exotique: Commons-IO
Extraire le fichier zip et tous ses sous-dossiers, en utilisant uniquement le JDK:
private void extractFolder(Ssortingng zipFile,Ssortingng extractFolder) { try { int BUFFER = 2048; File file = new File(zipFile); ZipFile zip = new ZipFile(file); Ssortingng newPath = extractFolder; new File(newPath).mkdir(); Enumeration zipFileEnsortinges = zip.ensortinges(); // Process each entry while (zipFileEnsortinges.hasMoreElements()) { // grab a zip file entry ZipEntry entry = (ZipEntry) zipFileEnsortinges.nextElement(); Ssortingng currentEntry = entry.getName(); File destFile = new File(newPath, currentEntry); //destFile = new File(newPath, destFile.getName()); File destinationParent = destFile.getParentFile(); // create the parent directory structure if needed destinationParent.mkdirs(); if (!entry.isDirectory()) { BufferedInputStream is = new BufferedInputStream(zip .getInputStream(entry)); int currentByte; // establish buffer for writing file byte data[] = new byte[BUFFER]; // write the current file to disk FileOutputStream fos = new FileOutputStream(destFile); BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER); // read and write until last byte is encountered while ((currentByte = is.read(data, 0, BUFFER)) != -1) { dest.write(data, 0, currentByte); } dest.flush(); dest.close(); is.close(); } } } catch (Exception e) { Log("ERROR: "+e.getMessage()); } }
Fichiers Zip et tous ses sous-dossiers:
private void addFolderToZip(File folder, ZipOutputStream zip, Ssortingng baseName) throws IOException { File[] files = folder.listFiles(); for (File file : files) { if (file.isDirectory()) { addFolderToZip(file, zip, baseName); } else { Ssortingng name = file.getAbsolutePath().subssortingng(baseName.length()); ZipEntry zipEntry = new ZipEntry(name); zip.putNextEntry(zipEntry); IOUtils.copy(new FileInputStream(file), zip); zip.closeEntry(); } } }
Une autre option que vous pouvez consulter est zt-zip disponible sur la page centrale et la page de projet de Maven à l’ adresse https://github.com/zeroturnaround/zt-zip.
Il dispose des fonctionnalités standard de conditionnement et de déballage (sur les stream et sur le système de fichiers) + de nombreuses méthodes d’assistance pour tester les fichiers dans une archive ou append / supprimer des entrées.
Téléchargez le fichier JAR et ajoutez-le au chemin de génération de votre projet. La class
ci class
dessous peut compresser et extraire n’importe quel fichier ou dossier, avec ou sans protection par mot de passe.
import java.io.File; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.util.Zip4jConstants; import net.lingala.zip4j.core.ZipFile; public class Compressor { public static void zip(Ssortingng targetPath, Ssortingng destinationFilePath, Ssortingng password) { try { ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); if(password.length()>0){ parameters.setEncryptFiles(true); parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES); parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256); parameters.setPassword(password); } ZipFile zipFile = new ZipFile(destinationFilePath); File targetFile = new File(targetPath); if(targetFile.isFile()){ zipFile.addFile(targetFile, parameters); }else if(targetFile.isDirectory()){ zipFile.addFolder(targetFile, parameters); } } catch (Exception e) { e.printStackTrace(); } } public static void unzip(Ssortingng targetZipFilePath, Ssortingng destinationFolderPath, Ssortingng password) { try { ZipFile zipFile = new ZipFile(targetZipFilePath); if (zipFile.isEncrypted()) { zipFile.setPassword(password); } zipFile.extractAll(destinationFolderPath); } catch (Exception e) { e.printStackTrace(); } } /**/ /// for test only public static void main(Ssortingng[] args) { Ssortingng targetPath = "target\\file\\or\\folder\\path"; Ssortingng zipFilePath = "zip\\file\\Path"; Ssortingng unzippedFolderPath = "destination\\folder\\path"; Ssortingng password = "your_password"; // keep it EMPTY<""> for applying no password protection Compressor.zip(targetPath, zipFilePath, password); Compressor.unzip(zipFilePath, unzippedFolderPath, password); }/**/ }
Un très beau projet est TrueZip .
TrueZIP est un framework de plug-in basé sur Java pour les systèmes de fichiers virtuels (VFS) qui fournit un access transparent aux fichiers d’archive comme s’il s’agissait de simples répertoires
Par exemple (à partir du site Web ):
File file = new TFile("archive.tar.gz/README.TXT"); OutputStream out = new TFileOutputStream(file); try { // Write archive entry contents here. ... } finally { out.close(); }
Une autre option est JZlib . D’après mon expérience, c’est moins “centré sur les fichiers” que zip4J, donc si vous devez travailler sur des objects blob en mémoire plutôt que sur des fichiers, vous voudrez peut-être y jeter un coup d’oeil.
Il y a un exemple complet ici pour compresser et décompresser les fichiers récursivement: http://developer-tips.hubpages.com/hub/Zipping-and-Unzipping-Nested-Directories-in-Java-using-Apache-Commons-Compress
Avez-vous consulté http://commons.apache.org/vfs/ ? Il prétend simplifier beaucoup de choses pour vous. Mais je ne l’ai jamais utilisé dans un projet.
Je ne connais pas non plus les bibliothèques de compression Java-Native autres que JDK ou Apache Compression.
Je me souviens qu’une fois que nous avons extrait certaines fonctionnalités d’Apache Ant – elles ont beaucoup d’utils pour la compression / décompression intégrée.
Un exemple de code avec VFS ressemblerait à ceci:
File zipFile = ...; File outputDir = ...; FileSystemManager fsm = VFS.getManager(); URI zip = zipFile.toURI(); FileObject packFileObject = fsm.resolveFile(packLocation.toSsortingng()); FileObject to = fsm.toFileObject(destDir); FileObject zipFS; try { zipFS = fsm.createFileSystem(packFileObject); fsm.toFileObject(outputDir).copyFrom(zipFS, new AllFileSelector()); } finally { zipFS.close(); }