2016-02-11 18 views
6

Sono consapevole del fatto che Oracle rileva i metodi di compressione/decompressione dei file ZIP/GZIP on their website. Ma ho uno scenario in cui ho bisogno di scansionare e scoprire se sono coinvolti ZIP/RAR annidati. Ad esempio, il seguente caso:Libreria di utilità Java per la gestione dei file ZIP nidificati

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

So che scorta apache comprimono pacchetto e java.util.zip sono i pacchetti wideley utilizzato dove scorta comprimono effettivamente soddisfa le caratteristiche mancanti in java.util.zip esempio qualche impostazione del personaggio mentre si fa lo zipout. Ma quello di cui non sono sicuro sono le utilità per la ricorsione attraverso i file zip annidati e le risposte fornite su SO non sono dei buoni esempi per farlo. Ho provato il seguente codice (che ho avuto da Oracle blog), ma come sospettavo, la directory nidificato ricorsione fallisce perché semplicemente non riesce a trovare i file:

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

Può essere che sto facendo qualcosa di sbagliato - o utilizzando il utilità sbagliate. Il mio obiettivo è identificare se uno qualsiasi dei file o file zip annidati ha estensioni di file che non sto permettendo. Questo per assicurarmi che possa impedire ai miei utenti di caricare file proibiti anche quando li stanno zippando. Ho anche la possibilità di usare Tika che può fare l'analisi ricorsiva (usando la soluzione di Zukka Zitting), ma non sono sicuro di poter usare i metadati per fare questo rilevamento come voglio.

Qualsiasi aiuto/suggerimento è apprezzato.

+0

non dovresti aprendo il Nested Zip dal flusso di input della zip esterna, piuttosto che dal nome del file (che non funzionerà in quanto il file si trova nel file zip non sul filesystem)? – Gagravarr

risposta

2

Utilizzando Commons Compress sarebbe più facile, anche perché dispone di interfacce comuni sensibili tra i vari decompressione che rendono la vita più facile + consente la manipolazione di altri formati di compressione (per esempio tar), allo stesso tempo

Se si vuole utilizzare solo il supporto Zip built-in, io suggerirei di fare qualcosa di simile:

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

il codice fallirà come si sta cercando di leggere inner.zip all'interno outer.zip come file locale, ma doesn' esiste come un file standalone Il codice qui sopra elaborare le cose che terminano con .zip come un altro file zip, e ricorsivamente

Probabilmente si desidera utilizzare comuni comprimere, però, in modo da poter gestire le cose con nomi alternativi, altri formati di compressione, ecc

+0

È una soluzione semplice, ma non viene inoltrata tramite .RAR. Ho provato con Tika ma richiede parecchio tempo per analizzare i metadati (probabilmente perché sta analizzando il tutto). – ha9u63ar

+0

Posso vedere che posso sostituire ZipInputStream con 'ZipArchiveInputStream' ma quale stream devo usare per RAR/TAR. Dovrei mantenere 'ArchiveInputStream' e' ArchiveEntry' fino in fondo? – ha9u63ar

+0

Se si desidera lavorare con tutti i formati con Commons Compress, utilizzare le classi Archive generali. Per un buon esempio, vedi il [codice sorgente del parser dei pacchetti Apache Tika] (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

Problemi correlati