2010-08-31 4 views
10

Ich möchte so etwas wie dies in meinem Programm tun:Dienstprogramm ein ganzes Archiv in ein Verzeichnis in Java entpacken

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

Ich kann unmöglich sein, die erste aus einem Programm zu tun. Wo finde ich eine Utility-Methode wie oben? Ich versuchte, Apache Commons-Io zu sehen, aber nichts da. Also, wo soll ich hinschauen?

+0

Ich habe dies als Feature-Anfrage bei Apache commons-compress hinzugefügt: https://issues.apache.org/jira/browse/COMPRESS-118 – eirikma

+5

Wir haben jetzt 2011 und es gibt nicht einmal eine (gemeinsame) 3rd-Party-Bibliothek, um eine ZIP in Java mit einem einzigen Aufruf zu extrahieren? WTF – Kutzi

Antwort

0

Es scheint, wie es möglich ist, zu tun, was ich will die TrueZip Bibliothek: https://truezip.dev.java.net/manual-6.html#Copying

Dies ist keine ideale Situation, da die Bibliothek ist recht groß und mit einem größeren Umfang, als ich brauche (und auch mit einigen eigenartigen und verwirrenden Details, wie zum Beispiel um Unterklassen von java.io.File organisiert zu sein, die auch Datei für die Verwendung in Klassen genannt werden, die typischerweise auch java.io.File-Instanzen behandeln!).

Zumindest muss ich nicht in einer Situation sein, in der eine Mehrheit der Codezeilen in der Klasse nicht mit der Verantwortung der Klasse in Verbindung stehen, oder eine komplexe Dienstprogrammklasse in dem Projekt zu halten, die nicht verwandt ist Zweck des Moduls.

Ich denke, dies ist ein typisches Beispiel für den Hauptgrund, warum erfahrene Entwickler von Java zu Ruby migrieren. Trotz einer Fülle von Bibliotheken in Java sind zu viele von ihnen schlecht entworfen, so dass einfache Operationen genauso schwierig durchzuführen sind wie die spezialisierteren. Scheint so, als würden sie von unten nach oben von Technikexperten geschrieben, die mehr darauf aus sind, alle Details und Möglichkeiten offenzulegen, als alltägliche Aufgaben zu vereinfachen. Die Apache-Commons-Leute verdienen Ehre, Bibliotheken zu erstellen, die Ihre Klasse von Codezeilen, insbesondere Schleifen und Bedingungen, die nicht mit dem Geschäftszweck der Klasse in Verbindung stehen, entlasten.

+0

hmm. funktioniert nicht genau so, wie ich es erwartet habe. Es recurses in die JAR-Dateien innerhalb der Zip und extrahiert sie auch trotz der Verwendung von Code das Handbuch sagt, wird das nicht tun. Nicht, was ich vorhatte. – eirikma

+0

Versuchen Sie TrueZIP 7. Die Klasse heißt jetzt TFile und ihre API ist sauber und produktiv. Wenn Sie Ruby-Ansatz mögen, könnte Ihnen das auch gefallen. –

1

Nun hat java.util.zip Klassen zu tun, was Sie in eine sehr straighforward Weise wollen

+0

Ich weiß, aber das ist nicht was ich meinte. Siehe Kommentar zur Antwort von jsshah unten. – eirikma

+1

Ich konnte dort keine Einzeiler finden. Fehle ich etwas, @helios? –

+0

Nr. Keine Einzeiler, nur Werkzeuge, um auf eine sehr direkte Weise zu implementieren, was gewollt ist. Lesen Sie eine Zip-Datei (ihre Einträge), für jeden Eintrag machen Sie dir, öffnen Sie die Datei, deponieren Sie den Inhalt und schließen Sie. Genau das, was Jsshah vorschlägt, aber vielleicht ein wenig kompakter (und Commons-Fileuploads "Streams.copy" verwendend). – helios

7

sehr alten Code, den ich in der Lage war

package com.den.frontend; 

import java.util zu graben. ; importieren Sie 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

danke, ihr beide, aber das ist nicht das, was ich meinte. Ich weiß, dass es möglich ist, zip-Einträge zu durchlaufen, die notwendigen Verzeichnisse zu erstellen und so und so mit der Standard-API. Ich will das alles nicht in meinem Programm. Es ist zu viel Code: Es ist hässlich und verwirrend. Es sollte nicht notwendig sein, dass alle Programme, die Dateien entpacken wollen, all diese Dinge enthalten. Ich möchte einen einzeiligen Befehl, um ein Archiv zu entpacken, genau wie Sie es in der Befehlszeile tun würden. Es ist schwer zu glauben, dass die ZipFile-Klasse keine unzipTo (Verzeichnis) -Methode hat. Stattdessen benötigt es 50 Zeilen, um das Gleiche zu tun. Was ist das für API-Design? – eirikma

+1

hmm. Vielleicht sollte ich versuchen, diese: Runtime.getRuntime() exec (new String [] { "entpacken", zipfile.getAbsolutePath(), "-d", destdir.getAbsolutePath(), });. – eirikma

+0

Der Vorteil der Verwendung einer JavaClass ist die Portabilität (Sie müssen sich keine Gedanken über native Binärdateien machen) – helios

6

Ich weiß, ich bin ziemlich spät zur Show, aber ich war auf der Suche nach dem gleichen und fand dies über Google. Der einfachste Weg, den ich gefunden habe, ist die Ameisen-Aufgabe "entpacken". Sie können es ohne komplizierten ant-Setup verwenden (es Sachen wie ProjectHelper ist ein komplettes ant-Projekt erstellen) aus Ihrer Java-Quelle, indem

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

Der Code zum Entpacken eine Datei in ein Verzeichnis wie folgt aussieht

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