2009-06-11 12 views
29

Tengo un archivo zip que contiene algunos otros archivos zip. Por ej. el archivo de correo es abc.zip y contiene xyz.zip, class1.java, class2.java. Y xyz.zip contiene el archivo class3.java y class4.java.¿Cómo descomprimir archivos recursivamente en Java?

Necesito extraer el archivo zip usando java a una carpeta que debe contener class1.java, class2.java, class3.java y class4.java.

+0

esto realmente lío hasta esta t pregunte: http://aioobe.org/zip-quine/. (Infinitamente recursivo zip-in-a-zip-in-a-zip-in-a- ..) – GKFX

+0

Solo un pensamiento, todas las respuestas que se presentan aquí en realidad no funcionan porque no ha considerado las cremalleras anidadas – ha9u63ar

Respuesta

-2
File dir = new File("BASE DIRECTORY PATH"); 
FileFilter ff = new FileFilter() { 

    @Override 
    public boolean accept(File f) { 
     //only want zip files 
     return (f.isFile() && f.getName().toLowerCase().endsWith(".zip")); 
    } 
}; 

File[] list = null; 
while ((list = dir.listFiles(ff)).length > 0) { 
    File file1 = list[0]; 
    //TODO unzip the file to the base directory 
} 
9

Aquí hay alguna base de código no probado en algún código anterior que tuve que descomprimir archivos.

public void doUnzip(String inputZip, String destinationDirectory) 
     throws IOException { 
    int BUFFER = 2048; 
    List zipFiles = new ArrayList(); 
    File sourceZipFile = new File(inputZip); 
    File unzipDestinationDirectory = new File(destinationDirectory); 
    unzipDestinationDirectory.mkdir(); 

    ZipFile zipFile; 
    // Open Zip file for reading 
    zipFile = new ZipFile(sourceZipFile, ZipFile.OPEN_READ); 

    // Create an enumeration of the entries in the zip file 
    Enumeration zipFileEntries = zipFile.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(unzipDestinationDirectory, currentEntry); 
     destFile = new File(unzipDestinationDirectory, destFile.getName()); 

     if (currentEntry.endsWith(".zip")) { 
      zipFiles.add(destFile.getAbsolutePath()); 
     } 

     // grab file's parent directory structure 
     File destinationParent = destFile.getParentFile(); 

     // create the parent directory structure if needed 
     destinationParent.mkdirs(); 

     try { 
      // extract file if not a directory 
      if (!entry.isDirectory()) { 
       BufferedInputStream is = 
         new BufferedInputStream(zipFile.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 (IOException ioe) { 
      ioe.printStackTrace(); 
     } 
    } 
    zipFile.close(); 

    for (Iterator iter = zipFiles.iterator(); iter.hasNext();) { 
     String zipName = (String)iter.next(); 
     doUnzip(
      zipName, 
      destinationDirectory + 
       File.separatorChar + 
       zipName.substring(0,zipName.lastIndexOf(".zip")) 
     ); 
    } 

} 
+0

¿Por qué tener una declaración de lanzamientos, y aún atrapar la excepción y registrarla? ¿Eso no significa que las personas que llaman esperarán IOExcepciones que nunca serán lanzadas ...? –

+0

¡Gracias por proporcionar esto, muy útil! –

+0

Bonito código hizo algunos ajustes y funciona bien, gracias – GFlam

5

Tomo ca.anderson4 y retire los zipfiles lista y volver a escribir un poco, esto es lo que tengo:

public class Unzip { 

public void unzip(String zipFile) throws ZipException, 
     IOException { 

    System.out.println(zipFile);; 
    int BUFFER = 2048; 
    File file = new File(zipFile); 

    ZipFile zip = new ZipFile(file); 
    String newPath = zipFile.substring(0, zipFile.length() - 4); 

    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(); 
     } 
     if (currentEntry.endsWith(".zip")) { 
      // found a zip file, try to open 
      unzip(destFile.getAbsolutePath()); 
     } 
    } 
} 

public static void main(String[] args) { 
    Unzip unzipper=new Unzip(); 
    try { 
     unzipper.unzip("test/test.zip"); 
    } catch (ZipException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

} 

he probado y funciona

+0

Ese código fue realmente escrito por ca.anderson4; Simplemente lo edité (no me gusta tener que desplazarme de lado a lado). –

+0

aaa okey, no lo vi :-). Así que le doy créditos a ca.anderson4 y al editor usted ;-) – fero46

+0

Este simplemente vuelca todos los archivos en todas las subcarpetas en una sola carpeta, destruyendo así la estructura de archivo completa – Ibolit

2

En las pruebas me di Archivo .mkDirs() no funciona bajo Windows ...

/** * para una ruta completa dada a crear todos los directorios padre **/

private void createParentHierarchy(String parentName) throws IOException { 
     File parent = new File(parentName); 
     String[] parentsStrArr = parent.getAbsolutePath().split(File.separator == "/" ? "/" : "\\\\"); 

     //create the parents of the parent 
     for(int i=0; i < parentsStrArr.length; i++){ 
      StringBuffer currParentPath = new StringBuffer(); 
      for(int j = 0; j < i; j++){ 
       currParentPath.append(parentsStrArr[j]+File.separator); 
      } 
      File currParent = new File(currParentPath.toString()); 
      if(!currParent.isDirectory()){ 
       boolean created = currParent.mkdir(); 
       if(isVerbose)log("creating directory "+currParent.getAbsolutePath()); 
      } 
     } 

     //create the parent itself 
     if(!parent.isDirectory()){ 
      boolean success = parent.mkdir(); 
     } 
    } 
64

Esta solución es muy similar a las soluciones anteriores ya publicadas, pero esta recrea la estructura de carpetas correcta al descomprimir.

static public void extractFolder(String zipFile) throws ZipException, IOException 
{ 
    System.out.println(zipFile); 
    int BUFFER = 2048; 
    File file = new File(zipFile); 

    ZipFile zip = new ZipFile(file); 
    String newPath = zipFile.substring(0, zipFile.length() - 4); 

    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(); 
     } 

     if (currentEntry.endsWith(".zip")) 
     { 
      // found a zip file, try to open 
      extractFolder(destFile.getAbsolutePath()); 
     } 
    } 
} 
+1

Esta función me salvó la vida. Algunas funciones zip pre-escritas en nuestro proyecto simplemente no pudieron extraer las carpetas dentro del archivo. Esto funciona genial Muchas gracias por compartir. – kingsmasher1

+1

Me sorprende cómo esta respuesta no fue aceptada. De todos modos, upvote para ti y gracias de nuevo. – kingsmasher1

+0

Gracias, esto funcionó de inmediato para mí. –

0

Igual que la respuesta de NeilMonday, pero extractos directorios vacíos:

static public void extractFolder(String zipFile) throws ZipException, IOException 
{ 
    System.out.println(zipFile); 
    int BUFFER = 2048; 
    File file = new File(zipFile); 

    ZipFile zip = new ZipFile(file); 
    String newPath = zipFile.substring(0, zipFile.length() - 4); 

    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(); 
     } 
     else{ 
      destFile.mkdirs() 
     } 
     if (currentEntry.endsWith(".zip")) 
     { 
      // found a zip file, try to open 
      extractFolder(destFile.getAbsolutePath()); 
     } 
    } 
} 
1

Uno debe cerrar el archivo zip después de descomprimir.

static public void extractFolder(String zipFile) throws ZipException, IOException 
{ 
    System.out.println(zipFile); 
    int BUFFER = 2048; 
    File file = new File(zipFile); 

    ZipFile zip = new ZipFile(file); 
    try 
    { 
     ...code from other answers (ex. NeilMonday)... 
    } 
    finally 
    { 
     zip.close(); 
    } 
} 
1

Modificado como era necesario, se mezcló en algunas de las mejores respuestas. Esta versión voluntad:

  • Extracto de forma recursiva una cremallera a la ubicación dada

  • Crear directorios vacíos

  • Cierre de cremallera adecuadamente


public static void unZipAll(File source, File destination) throws IOException 
{ 
    System.out.println("Unzipping - " + source.getName()); 
    int BUFFER = 2048; 

    ZipFile zip = new ZipFile(source); 
    try{ 
     destination.getParentFile().mkdirs(); 
     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(destination, 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 = null; 
       FileOutputStream fos = null; 
       BufferedOutputStream dest = null; 
       try{ 
        is = new BufferedInputStream(zip.getInputStream(entry)); 
        int currentByte; 
        // establish buffer for writing file 
        byte data[] = new byte[BUFFER]; 

        // write the current file to disk 
        fos = new FileOutputStream(destFile); 
        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); 
        } 
       } catch (Exception e){ 
        System.out.println("unable to extract entry:" + entry.getName()); 
        throw e; 
       } finally{ 
        if (dest != null){ 
         dest.close(); 
        } 
        if (fos != null){ 
         fos.close(); 
        } 
        if (is != null){ 
         is.close(); 
        } 
       } 
      }else{ 
       //Create directory 
       destFile.mkdirs(); 
      } 

      if (currentEntry.endsWith(".zip")) 
      { 
       // found a zip file, try to extract 
       unZipAll(destFile, destinationParent); 
       if(!destFile.delete()){ 
        System.out.println("Could not delete zip"); 
       } 
      } 
     } 
    } catch(Exception e){ 
     e.printStackTrace(); 
     System.out.println("Failed to successfully unzip:" + source.getName()); 
    } finally { 
     zip.close(); 
    } 
    System.out.println("Done Unzipping:" + source.getName()); 
} 
Cuestiones relacionadas