web-dev-qa-db-fra.com

Java Zip - comment décompresser un dossier?

Existe-t-il un exemple de code, comment décompresser en particulier un dossier de Zip dans le répertoire souhaité? J'ai lu tous les fichiers du dossier "FOLDER" dans le tableau d'octets, comment puis-je recréer à partir de sa structure de fichiers?

17
Waypoint

Je ne suis pas sûr de ce que vous entendez par particalement Voulez-vous dire le faire vous-même sans l'aide de l'API?

Dans le cas où cela ne vous dérangerait pas d'utiliser une bibliothèque opensource, il y a une API intéressante pour cela appelée Zip4J

Il est facile à utiliser et je pense qu’il ya de bons retours à ce sujet. Voir cet exemple:

String source = "folder/source.Zip";
String destination = "folder/source/";   

try {
    ZipFile zipFile = new ZipFile(source);
    zipFile.extractAll(destination);
} catch (ZipException e) {
    e.printStackTrace();
}

Si les fichiers que vous voulez décompresser ont des mots de passe, essayez ceci:

String source = "folder/source.Zip";
String destination = "folder/source/";
String password = "password";

try {
    ZipFile zipFile = new ZipFile(source);
    if (zipFile.isEncrypted()) {
        zipFile.setPassword(password);
    }
    zipFile.extractAll(destination);
} catch (ZipException e) {
    e.printStackTrace();
}

J'espère que c'est utile.

28
sfrj

Voici le code que j'utilise. Modifiez BUFFER_SIZE en fonction de vos besoins.

import Java.io.BufferedOutputStream;
import Java.io.File;
import Java.io.FileInputStream;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.util.Zip.ZipEntry;
import Java.util.Zip.ZipInputStream;

public class ZipUtils
{
  private static final int  BUFFER_SIZE = 4096;

  private static void extractFile(ZipInputStream in, File outdir, String name) throws IOException
  {
    byte[] buffer = new byte[BUFFER_SIZE];
    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(outdir,name)));
    int count = -1;
    while ((count = in.read(buffer)) != -1)
      out.write(buffer, 0, count);
    out.close();
  }

  private static void mkdirs(File outdir,String path)
  {
    File d = new File(outdir, path);
    if( !d.exists() )
      d.mkdirs();
  }

  private static String dirpart(String name)
  {
    int s = name.lastIndexOf( File.separatorChar );
    return s == -1 ? null : name.substring( 0, s );
  }

  /***
   * Extract zipfile to outdir with complete directory structure
   * @param zipfile Input .Zip file
   * @param outdir Output directory
   */
  public static void extract(File zipfile, File outdir)
  {
    try
    {
      ZipInputStream zin = new ZipInputStream(new FileInputStream(zipfile));
      ZipEntry entry;
      String name, dir;
      while ((entry = zin.getNextEntry()) != null)
      {
        name = entry.getName();
        if( entry.isDirectory() )
        {
          mkdirs(outdir,name);
          continue;
        }
        /* this part is necessary because file entry can come before
         * directory entry where is file located
         * i.e.:
         *   /foo/foo.txt
         *   /foo/
         */
        dir = dirpart(name);
        if( dir != null )
          mkdirs(outdir,dir);

        extractFile(zin, outdir, name);
      }
      zin.close();
    } 
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }
}
22
petrs

La même chose peut être obtenue en utilisant la bibliothèque Ant Compress. Cela préservera la structure du dossier.

Dépendance Maven: -

<dependency>
    <groupId>org.Apache.ant</groupId>
    <artifactId>ant-compress</artifactId>
    <version>1.2</version>
</dependency>

Exemple de code: -

Unzip unzipper = new Unzip();
unzipper.setSrc(theZIPFile);
unzipper.setDest(theTargetFolder);
unzipper.execute();
11
Kumar Sambhav

Voici une solution simple, conforme aux conventions les plus modernes. Vous voudrez peut-être réduire la taille de la mémoire tampon si vous décompressez des fichiers plus volumineux. Ceci afin que vous ne gardiez pas toutes les informations de fichiers en mémoire.

    public static void unzip(File source, String out) throws IOException {
    try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source))) {

        ZipEntry entry = zis.getNextEntry();

        while (entry != null) {

            File file = new File(out, entry.getName());

            if (entry.isDirectory()) {
                file.mkdirs();
            } else {
                File parent = file.getParentFile();

                if (!parent.exists()) {
                    parent.mkdirs();
                }

                try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) {

                    byte[] buffer = new byte[Math.toIntExact(entry.getSize())];

                    int location;

                    while ((location = zis.read(buffer)) != -1) {
                        bos.write(buffer, 0, location);
                    }
                }
            }
            entry = zis.getNextEntry();
        }
    }
}
2
user6186835

Voici un code complet plus "moderne" basé sur this post mais refactored (et utilisant Lombok ):

import lombok.experimental.var;
import lombok.val;

import Java.io.File;
import Java.io.FileInputStream;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.util.Zip.ZipInputStream;

import static Java.nio.file.Files.createDirectories;

public class UnZip
{
    public static void unZip(String sourceZipFile, String outputDirectory) throws IOException
    {
        val folder = new File(outputDirectory);
        createDirectories(folder.toPath());

        try (val zipInputStream = new ZipInputStream(new FileInputStream(sourceZipFile)))
        {
            var nextEntry = zipInputStream.getNextEntry();

            while (nextEntry != null)
            {
                val fileName = nextEntry.getName();
                val newFile = new File(outputDirectory + File.separator + fileName);

                createDirectories(newFile.getParentFile().toPath());
                writeFile(zipInputStream, newFile);

                nextEntry = zipInputStream.getNextEntry();
            }

            zipInputStream.closeEntry();
        }
    }

    private static void writeFile(ZipInputStream inputStream, File file) throws IOException
    {
        val buffer = new byte[1024];
        try (val fileOutputStream = new FileOutputStream(file))
        {
            int length;
            while ((length = inputStream.read(buffer)) > 0)
            {
                fileOutputStream.write(buffer, 0, length);
            }
        }
    }
}
0
BullyWiiPlaza

Vous devriez obtenir toutes les entrées de votre fichier Zip:

Enumeration entries = zipFile.getEntries();

ensuite, pour parcourir cette énumération, récupérez la ZipEntry, vérifiez s’il s’agit d’un répertoire ou non, créez un répertoire ou extrayez un fichier respectivement.

0
Alex Stybaev