2016-02-11 5 views
6

Ich bin mir bewusst, dass Oracle ZIP/GZIP-Datei Kompressor/Dekompressor-Methoden on their website notiert. Aber ich habe ein Szenario, in dem ich scannen und herausfinden muss, ob verschachtelte ZIPs/RARs beteiligt sind. Zum Beispiel kann der folgende Fall:Java-Dienstprogramm-Bibliothek für verschachtelte ZIP-Datei Handhabung

-MyFiles.zip 
    -MyNestedFiles.zip 
     -MyMoreNestedFiles.zip 
      -MoreProbably.zip 
     -Other_non_zips 
    -Other_non_zips 
-Other_non_zips 

Ich weiß, dass Apache Commons komprimieren Paket und java.util.zip sind die wideley verwendeten Pakete wo commons tatsächlich komprimieren, um die fehlenden Features in java.util.zip zum Beispiel bietet einige Zeicheneinstellungen während des Zipouts. Aber was ich nicht sicher bin, ist die Dienstprogramme für die Wiederholung durch verschachtelte Zip-Dateien und die Antworten auf SO sind nicht sehr gute Beispiele dafür. Ich habe versucht, den folgenden Code (was ich von Oracle Blog bekam), aber wie ich vermuten, die verschachtelte Verzeichnisrekursion schlägt fehl, weil es einfach die Dateien nicht finden kann:

public static void processZipFiles(String pathName) throws Exception{ 
     ZipInputStream zis = null; 
     InputStream is = null; 
     try { 
      ZipFile zipFile = new ZipFile(new File(pathName)); 
      String nestPathPrefix = zipFile.getName().substring(0, zipFile.getName().length() -4); 
      for(Enumeration e = zipFile.entries(); e.hasMoreElements();){ 
      ZipEntry ze = (ZipEntry)e.nextElement(); 
      if(ze.getName().contains(".zip")){ 
       is = zipFile.getInputStream(ze); 
       zis = new ZipInputStream(is); 
       ZipEntry zentry = zis.getNextEntry(); 

       while (zentry!=null){ 
        System.out.println(zentry.getName()); 
        zentry = zis.getNextEntry(); 
        ZipFile nestFile = new ZipFile(nestPathPrefix+"\\"+zentry.getName()); 
        if (zentry.getName().contains(".zip")) { 
         processZipFiles(nestPathPrefix+"\\"+zentry.getName()); 
        } 
       } 
       is.close(); 
      } 
      } 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally{ 
      if(is != null) 
       is.close(); 
      if(zis!=null) 
       zis.close(); 
     } 
    } 

Kann sein, ich etwas falsch mache - oder mit der falsche utils. Mein Ziel ist es, festzustellen, ob eine der Dateien oder verschachtelten Zip-Dateien Dateierweiterungen haben, die ich nicht erlaube. Dadurch kann ich verhindern, dass meine Benutzer verbotene Dateien hochladen, selbst wenn sie es zippen. Ich habe auch die Möglichkeit, Tika zu verwenden, die rekursives Parsing durchführen kann (mit der Lösung von Zukka Zitting), aber ich bin mir nicht sicher, ob ich die Metadaten verwenden kann, um diese Erkennung zu machen, wie ich will.

Jede Hilfe/Vorschlag wird geschätzt.

+0

umgehen können, sollten Sie nicht Öffnen Sie die verschachtelte Zip-Datei aus dem Eingabe-Stream des äußeren Zip-Eintrags und nicht nach dem Dateinamen (was nicht funktionieren wird, da sich die Datei in der Zip-Datei und nicht im Dateisystem befindet)? – Gagravarr

Antwort

2

Commons Kompresse wäre einfacher, nicht zuletzt, weil es sinnvoll, gemeinsam genutzten Schnittstellen zwischen den verschiedenen Dekomprimierprogramme hat das Leben + leichter ermöglicht Umgang mit anderen Komprimierungsformaten (zB Teer) zur gleichen Zeit

Wenn Sie möchten, nur die eingebauten Zip-Unterstützung zu verwenden, würde ich vorschlagen, dass Sie so etwas tun:

File file = new File("outermost.zip"); 
FileInputStream input = new FileInputStream(file); 
check(input, file.toString()); 

public static void check(InputStream compressedInput, String name) { 
    ZipInputStream input = new ZipInputStream(compressedInput); 
    ZipEntry entry = null; 
    while ((entry = input.getNextEntry()) != null) { 
     System.out.println("Found " + entry.getName() + " in " + name); 
     if (entry.getName().endsWith(".zip")) { // TODO Better checking 
     check(input, name + "/" + entry.getName()); 
     } 
    } 
} 

Ihr Code wird nicht, wie Sie inner.zip innerhalb outer.zip als lokale Datei zu lesen sind versucht, aber es doesn‘ t existieren als eigenständige Datei. Der obige Code wird die Dinge verarbeiten mit .zip als eine andere ZIP-Datei mit der Endung und wird

Sie wahrscheinlich commons verwenden möchten Rekursion obwohl komprimieren, so dass Sie Dinge mit alternativen Dateinamen, andere Komprimierungsformate etc

+0

Es ist eine einfache Lösung, aber nicht durch .RAR. Ich habe es mit Tika versucht, aber es dauert ziemlich lange, die Metadaten zu parsen (möglicherweise, weil es das Ganze analysiert). – ha9u63ar

+0

Ich kann sehen, dass ich den ZipInputStream mit 'ZipArchiveInputStream' ersetzen kann, aber welchen Stream verwende ich für RAR/TAR. Soll ich "ArchiveInputStream" und "ArchiveEntry" vollständig beibehalten? – ha9u63ar

+0

Wenn Sie mit allen Formaten mit Commons Compress arbeiten möchten, verwenden Sie die allgemeinen Archivklassen. Ein gutes Beispiel dafür finden Sie im [Apache Tika Packages Parser Quellcode] (https://git1-us-west.apache.org/repos/asf?p=tika.git;a=blob;f=tika -parsers/src/main/java/org/apache/tika/parser/pkg/CompressorParser.java; hb = HEAD) – Gagravarr

Verwandte Themen