2010-08-31 3 views
10

Je voudrais faire quelque chose comme ça dans mon programme:utilitaire pour décompresser une archive entière dans un répertoire java

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

Je ne peux pas être le premier à le faire à partir d'un programme. Où puis-je trouver une méthode d'utilité comme ci-dessus? J'ai essayé de regarder apache commons-io, mais rien là. Alors, où dois-je regarder?

+0

J'ai ajouté cela comme une demande de fonctionnalité à Apache commons-compress: https://issues.apache.org/jira/browse/COMPRESS-118 – eirikma

+5

Nous avons maintenant 2011 et il n'y a même pas (commune) Bibliothèque tierce pour extraire un ZIP en Java avec un seul appel? WTF – Kutzi

Répondre

0

Il semble que il est possible de faire ce que je veux utiliser la bibliothèque TrueZip: https://truezip.dev.java.net/manual-6.html#Copying

Ce n'est pas une situation idéale, car la bibliothèque est assez grande et avec une portée plus grande que j'ai besoin (et aussi avec des détails particuliers et déroutants tels que l'organisation autour des sous-classes de java.io.File qui sont aussi appelées Fichier à utiliser dans les classes qui gèrent généralement les instances de java.io.File!). Au moins, je n'ai pas besoin d'être dans une situation où la majorité des lignes de code de la classe ne sont pas liées à la responsabilité de la classe, ou de maintenir une classe d'utilitaire complexe dans le projet qui n'est pas liée à la classe but du module.

Je pense que c'est un exemple typique de la raison principale pour laquelle les développeurs expérimentés migrent de Java vers Ruby. Malgré l'abondance des bibliothèques en java, un trop grand nombre d'entre elles sont mal conçues, de sorte que les opérations simples deviennent tout aussi difficiles à exécuter que les opérations plus spécialisées. On dirait qu'ils sont écrits de bas en haut par des experts en technologie plus désireux d'exposer tous les détails et les possibilités que de rendre les tâches quotidiennes simples. Les gens d'apache commons méritent l'honneur de créer des bibliothèques qui soulagent votre classe des lignes de code, en particulier des boucles et des conditionnelles, qui ne sont pas liées à l'objectif de la classe.

+0

hmm. ne fonctionne pas exactement comme je m'y attendais. il récursive dans les fichiers jar à l'intérieur du zip et les extrait aussi malgré moi en utilisant le code que le manuel dit ne le fera pas. Pas ce que j'avais en tête. – eirikma

+0

Essayez TrueZIP 7. La classe est maintenant appelée TFile et son API est propre et productive. Si vous aimez l'approche de Ruby, vous pourriez aussi aimer ça. –

1

Eh bien, java.util.zip a des classes à faire ce que vous voulez dans une très straighforward façon

+0

Je sais, mais ce n'est pas ce que je voulais dire. Voir le commentaire sur la réponse par jsshah ci-dessous. – eirikma

+1

Je n'ai pas trouvé de doublure. Ai-je oublié quelque chose, @helios? –

+0

Non. Pas d'interlocuteurs, juste des outils à mettre en œuvre de façon très directe, ce que l'on veut. Lire un fichier zip (ses entrées), pour chaque entrée faire dir, ouvrir le fichier, vider le contenu, et fermer. Juste ce que jsshah propose mais peut-être un peu plus compact (et en utilisant 'Streams.copy' de commons-fileupload). – helios

7

code très vieux que j'ai pu creuser

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

merci, tous les deux, mais ce n'est pas ce que je voulais dire. Je sais qu'il est possible de traverser les entrées zip, créer les répertoires nécessaires et ainsi de suite en utilisant l'API std. Je ne veux pas tout ça dans mon programme. C'est trop de code: c'est moche et déroutant. Il ne devrait pas être nécessaire pour tous les programmes qui veulent décompresser les fichiers d'inclure tout cela. Je veux une commande sur une seule ligne pour décompresser une archive, comme vous le feriez sur la ligne de commande. Il est difficile de croire que la classe ZipFile n'a pas de méthode unzipTo (directory). Au lieu de cela, il faut 50 lignes pour faire la même chose. Qu'est-ce que c'est pour la conception de l'API? – eirikma

+1

hmm. Peut-être que je devrais essayer ceci: Runtime.getRuntime() exec (new String [] { "décompressez", zipfile.getAbsolutePath(), "-d", destdir.getAbsolutePath(), });. – eirikma

+0

L'avantage d'utiliser JavaClass est la portabilité (vous n'avez pas à vous soucier des binaires natifs) – helios

6

Je sais que je suis, assez tard pour le spectacle, mais je cherchais la même chose et l'ai trouvé via google. Le moyen le plus simple que j'ai trouvé est la tâche ant "unzip". Vous pouvez l'utiliser sans aucune configuration fourmi compliqué (il y a des choses comme ProjectHelper pour construire un projet fourmi complet) de votre source java en incluant

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

Le code pour décompresser un fichier dans un répertoire ressemble à ceci

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