Qu'est ce qu'une bonne bibliothèque Java pour compresser/décompresser des fichiers? [fermé]


J'ai regardé la bibliothèque Zip par défaut fournie avec le JDK et les bibliothèques de compression Apache et je ne suis pas satisfait d'eux pour 3 raisons:

  1. Ils sont gonflés et ont une mauvaise conception d'API. Je dois écrire 50 lignes de sortie de tableau d'octets de plaque de chaudière, d'entrée zip, de fichiers de flux et de fermer les flux pertinents, d'attraper des exceptions et de déplacer des tampons d'octets par moi-même? Pourquoi ne puis-je pas avoir une API simple qui ressemble à ceci Zipper.unzip(InputStream zipFile, File targetDirectory, String password = null) et Zipper.zip(File targetDirectory, String password = null) qui fonctionne simplement?

  2. Il il semble que le décompressage zippé détruit les méta-données du fichier et que la gestion du mot de passe soit interrompue.

  3. De plus, toutes les bibliothèques que j'ai essayées étaient 2-3x lentes par rapport aux outils zip en ligne de commande que j'obtiens avec UNIX?

Pour moi (2) et (3) sont des points mineurs mais je veux vraiment une bonne bibliothèque testée avec une interface d'une ligne.

Author: pathikrit, 2012-02-17

9 answers

Je sais que sa fin et il y a beaucoup de réponses, mais ce zip4j est l'une des meilleures bibliothèques pour la compression j'ai utilisé. Son simple (pas de code 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(){
    String source = "some/compressed/file.zip";
    String destination = "some/destination/folder";
    String 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 Maven est:

<dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>1.3.2</version>
</dependency>
 249
Author: user2003470, 2015-04-28 02:26:18

Avec Apache Commons-IO's IOUtils vous pouvez faire ceci:

java.util.zip.ZipFile zipFile = new ZipFile(file);
try {
  Enumeration<? extends ZipEntry> entries = zipFile.entries();
  while (entries.hasMoreElements()) {
    ZipEntry entry = entries.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 toujours du code standard, mais il n'a qu'une seule dépendance non exotique: Commons-IO

 53
Author: Geoffrey De Smet, 2016-07-27 19:40:42

Extraire le fichier zip et tous ses sous-dossiers, en utilisant uniquement le JDK:

private void extractFolder(String zipFile,String extractFolder) 
{
    try
    {
        int BUFFER = 2048;
        File file = new File(zipFile);

        ZipFile zip = new ZipFile(file);
        String newPath = extractFolder;

        new File(newPath).mkdir();
        Enumeration zipFileEntries = zip.entries();

        // Process each entry
        while (zipFileEntries.hasMoreElements())
        {
            // grab a zip file entry
            ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
            String 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, String baseName) throws IOException {
    File[] files = folder.listFiles();
    for (File file : files) {
        if (file.isDirectory()) {
            addFolderToZip(file, zip, baseName);
        } else {
            String name = file.getAbsolutePath().substring(baseName.length());
            ZipEntry zipEntry = new ZipEntry(name);
            zip.putNextEntry(zipEntry);
            IOUtils.copy(new FileInputStream(file), zip);
            zip.closeEntry();
        }
    }
}
 23
Author: Bashir Beikzadeh, 2016-03-04 17:02:26

Une autre option que vous pouvez consulter est zt-zip disponible à partir de Maven central et de la page du projet à https://github.com/zeroturnaround/zt-zip

Il a la fonctionnalité standard d'emballage et de déballage (sur les flux et sur le système de fichiers) + beaucoup de méthodes d'aide pour tester les fichiers dans une archive ou ajouter/supprimer des entrées.

 17
Author: toomasr, 2013-05-01 14:23:53

Implémentation complète pour Compresser / Décompresser un dossier / Fichier avec zip4j


Téléchargez le jar depuisici , etajoutez-le au chemin de construction de votre projet. Le class ci-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(String targetPath, String destinationFilePath, String 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(String targetZipFilePath, String destinationFolderPath, String 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(String[] args) {

        String targetPath = "target\\file\\or\\folder\\path";
        String zipFilePath = "zip\\file\\Path"; 
        String unzippedFolderPath = "destination\\folder\\path";
        String password = "your_password"; // keep it EMPTY<""> for applying no password protection

        Compressor.zip(targetPath, zipFilePath, password);
        Compressor.unzip(zipFilePath, unzippedFolderPath, password);
    }/**/
}
 11
Author: Minhas Kamal, 2018-01-09 05:05:37

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 accès 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();
}
 7
Author: Michael, 2012-02-17 08:32:46

Une autre option est JZlib. D'après mon expérience, il est moins "centré sur les fichiers" que zip4J, donc si vous devez travailler sur des blobs en mémoire plutôt que sur des fichiers, vous voudrez peut-être y jeter un œil.

 2
Author: Henrik Aasted, 2013-09-20 07:55:08

Il y a un exemple complet ici pour compresser et décompresser des fichiers récursivement: http://developer-tips.hubpages.com/hub/Zipping-and-Unzipping-Nested-Directories-in-Java-using-Apache-Commons-Compress

 0
Author: user1491819, 2015-02-15 05:53:35

Avez-vous regardé http://commons.apache.org/vfs / ? Il prétend simplifier beaucoup de choses pour vous. Mais je n'ai jamais utilisé dans un projet.

Je ne connais pas non plus les bibliothèques de compression Java natives autres que la compression JDK ou Apache.

Je me souviens d'une fois que nous avons arraché certaines fonctionnalités d'Apache Ant - ils ont beaucoup d'utils pour la compression / décompression intégrés.

Exemple de code avec VFS ressemblerait à:

File zipFile = ...;
File outputDir = ...;
FileSystemManager fsm = VFS.getManager();
URI zip = zipFile.toURI();
FileObject packFileObject = fsm.resolveFile(packLocation.toString());
FileObject to = fsm.toFileObject(destDir);
FileObject zipFS;
try {
    zipFS = fsm.createFileSystem(packFileObject);
    fsm.toFileObject(outputDir).copyFrom(zipFS, new AllFileSelector());
} finally {
    zipFS.close();
}
 0
Author: wemu, 2015-05-07 21:49:29