2010-08-31 21 views
10

me gustaría hacer algo como esto en mi programa:utilidad para descomprimir un archivo completo en un directorio en Java

File zipFile = .....; 
File destDir = ....;  
ImaginaryZipUtility.unzipAllTo(zipFile, destdir); 

No puedo ser el primero en hacerlo desde un programa. ¿Dónde encuentro un método de utilidad como el anterior? Traté de mirar apache commons-io, pero nada allí. Entonces, ¿dónde debería mirar?

+0

Agregué esto como una solicitud de función en Apache commons-compress: https://issues.apache.org/jira/browse/COMPRESS-118 – eirikma

+5

Tenemos ahora 2011 y no hay ni siquiera un (común) Biblioteca de terceros para extraer un archivo ZIP en Java con una sola llamada? WTF – Kutzi

Respuesta

0

Parece que es posible hacer lo que quiera usar la biblioteca TrueZIP: https://truezip.dev.java.net/manual-6.html#Copying

Esto no es una situación ideal, ya que la biblioteca es bastante grande y con un alcance más amplio de lo que necesito (y también con algunos detalles peculiares y confusos, como organizarse en torno a subclases de java.io.File que también se denominan Archivo para usar en clases que normalmente también manejan instancias de java.io.File.

Al menos no tengo que estar en una situación donde la mayoría de las líneas de código en la clase no están relacionadas con la responsabilidad de la clase, o mantener una clase de utilidad compleja en el proyecto que no está relacionada con la clase propósito del módulo.

Creo que este es un ejemplo típico de la razón principal por la cual los desarrolladores experimentados están migrando de Java a Ruby. A pesar de la abundancia de bibliotecas en Java, muchas de ellas están mal diseñadas para que las operaciones simples se vuelvan tan difíciles de realizar como las más especializadas. Parece que están escritos desde abajo hacia arriba por expertos en tecnología más ansiosos por exponer todos los detalles y posibilidades que hacer que las tareas cotidianas sean simples. La gente de apache commons merece honor por crear bibliotecas que alivian a su clase de las líneas de código, especialmente los bucles y condicionales, que no están relacionados con el objetivo comercial de la clase.

+0

hmm. no funciona exactamente como esperaba vuelve a aparecer en los archivos jar dentro del zip y los extrae también a pesar de que use el código que el manual dice que no hará eso. No es lo que tenía en mente. – eirikma

+0

Pruebe TrueZIP 7. La clase ahora se llama TFile y su API es limpia y productiva. Si te gusta el enfoque de Ruby, también te puede gustar esto. –

1

Bueno, java.util.zip tiene clases para hacer lo que quiere de un modo muy directo conducir

+0

Lo sé, pero eso no es lo que quise decir. Ver el comentario sobre la respuesta de jsshah a continuación. – eirikma

+1

No pude encontrar ninguno. ¿Me estoy perdiendo algo, @helios? –

+0

No. No hay líneas rectas, solo herramientas para implementar de una manera muy directa, lo que se quiere. Lea un archivo zip (sus entradas), para cada entrada, haga dir, abra el archivo, vacíe el contenido y cierre. Justo lo que jsshah propone, pero quizás un poco más compacto (y el uso de 'Streams.copy' de commons-fileupload). – helios

7

código muy antiguo que yo era capaz de desenterrar

package com.den.frontend; 

import java.util. ; import java.util.zip.; import java.io. *;

public class ZIPUtility 
{ 
    public static final int BUFFER_SIZE = 2048; 

    //This function converts the zip file into uncompressed files which are placed in the 
    //destination directory 
    //destination directory should be created first 
    public static boolean unzipFiles(String srcDirectory, String srcFile, String destDirectory) 
    { 
     try 
     { 
      //first make sure that all the arguments are valid and not null 
      if(srcDirectory == null) 
      { 
       System.out.println(1); 
       return false; 
      } 
      if(srcFile == null) 
      { 
       System.out.println(2); 
       return false; 
      } 
      if(destDirectory == null) 
      { 
       System.out.println(3); 
       return false; 
      } 
      if(srcDirectory.equals("")) 
      { 
       System.out.println(4); 
       return false; 
      } 
      if(srcFile.equals("")) 
      { 
       System.out.println(5); 
       return false; 
      } 
      if(destDirectory.equals("")) 
      { 
       System.out.println(6); 
       return false; 
      } 
      //now make sure that these directories exist 
      File sourceDirectory = new File(srcDirectory); 
      File sourceFile = new File(srcDirectory + File.separator + srcFile); 
      File destinationDirectory = new File(destDirectory); 

      if(!sourceDirectory.exists()) 
      { 
       System.out.println(7); 
       return false; 
      } 
      if(!sourceFile.exists()) 
      { 
       System.out.println(sourceFile); 
       return false; 
      } 
      if(!destinationDirectory.exists()) 
      { 
       System.out.println(9); 
       return false; 
      } 

      //now start with unzip process 
      BufferedOutputStream dest = null; 

      FileInputStream fis = new FileInputStream(sourceFile); 
      ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis)); 

      ZipEntry entry = null; 

      while((entry = zis.getNextEntry()) != null) 
      { 
       String outputFilename = destDirectory + File.separator + entry.getName(); 

       System.out.println("Extracting file: " + entry.getName()); 

       createDirIfNeeded(destDirectory, entry); 

       int count; 

       byte data[] = new byte[BUFFER_SIZE]; 

       //write the file to the disk 
       FileOutputStream fos = new FileOutputStream(outputFilename); 
       dest = new BufferedOutputStream(fos, BUFFER_SIZE); 

       while((count = zis.read(data, 0, BUFFER_SIZE)) != -1) 
       { 
        dest.write(data, 0, count); 
       } 

       //close the output streams 
       dest.flush(); 
       dest.close(); 
      } 

      //we are done with all the files 
      //close the zip file 
      zis.close(); 

     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
      return false; 
     } 

     return true; 
    } 

    private static void createDirIfNeeded(String destDirectory, ZipEntry entry) 
    { 
     String name = entry.getName(); 

     if(name.contains("/")) 
     { 
      System.out.println("directory will need to be created"); 

      int index = name.lastIndexOf("/"); 
      String dirSequence = name.substring(0, index); 

      File newDirs = new File(destDirectory + File.separator + dirSequence); 

      //create the directory 
      newDirs.mkdirs(); 
     } 
    } 

} 
+2

gracias, ambos, pero eso no es lo que quise decir. Sé que es posible atravesar entradas zip, crear los directorios necesarios y algo así usando la api estándar. No quiero todo eso en mi programa. Es demasiado código: es feo y confuso. No debería ser necesario que todos los programas que desean descomprimir archivos incluyan todo eso. Quiero un comando de una sola línea para descomprimir un archivo, al igual que lo haría en la línea de comandos. Es difícil creer que la clase ZipFile no tenga un método UnzipTo (directorio). En cambio, requiere 50 líneas para hacer lo mismo. ¿Qué es eso para el diseño de API? – eirikma

+1

hmm. Tal vez debería intentar esto: Runtime.getRuntime() exec (nueva String [] { "descomprimir", zipfile.getAbsolutePath(), "-d", destdir.getAbsolutePath(), });. – eirikma

+0

La ventaja de utilizar JavaClass es la portabilidad (no tiene que preocuparse por los binarios nativos) – helios

6

Sé que soy, bastante tarde para el espectáculo, pero estaba buscando lo mismo y encontré esto a través de Google. La forma más fácil que encontré es la tarea de hormiga "descomprimir". Se puede utilizar sin ningún tipo de configuración de hormigas complicada (hay cosas por el estilo ProjectHelper para construir un proyecto de hormigas completa) de su fuente de Java mediante la inclusión de

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

El código para descomprimir un archivo en un directorio tiene este aspecto

org.apache.ant.compress.taskdefs.Unzip u = new Unzip(); 
u.setSrc(new File("<archive.zip>")); 
u.setDest(new File("<targetDir>")); 
u.execute(); 
Cuestiones relacionadas