2016-02-11 2 views
6

Я знаю, что Oracle замечает методы сжатия/декомпрессии файлов ZIP/GZIP on their website. Но у меня есть сценарий, где мне нужно сканировать и выяснить, вовлечены ли какие-либо вложенные ZIP/RAR. Например, следующий случай:Библиотека утилиты Java для обработки вложенных ZIP-файлов

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

Я знаю, что Apache Commons сжать пакет и java.util.zip являются wideley используются пакеты, где Обще сжимают фактически обслуживает недостающие функции в java.util.zip, например, некоторые настройки персонажа при выполнении zipouts. Но я не уверен в том, что утилиты для рекурсии через вложенные файлы zip и ответы, представленные на SO, не очень хорошие примеры этого. Я попытался следующий код (который я получил от блога Oracle), но, как я подозревал, вложенная каталог рекурсии не удается, потому что он просто не может найти файлы:

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

Может быть, я делаю что-то неправильно - или с помощью неправильные утилиты. Моя цель - определить, получили ли файлы или вложенные zip-файлы расширения файлов, которые я не разрешаю. Это делается для того, чтобы я мог запретить моим пользователям загружать запрещенные файлы, даже когда они их застегивают. У меня также есть возможность использовать Tika, который может выполнять рекурсивный синтаксический анализ (используя решение Zukka Zitting), но я не уверен, могу ли я использовать метаданные для этого обнаружения, как я хочу.

Любая помощь/предложение оценены.

+0

ты не должен открыть вкладку «Вложенный Zip» из входного потока внешней записи zip, а не по имени файла (что не будет работать, поскольку файл находится в zip не в файловой системе)? – Gagravarr

ответ

2

Использование Commons Сжать было бы проще, не в последнюю очередь потому, что она имеет разумные общие интерфейсы между различными декомпрессоров, которые делают жизнь проще + позволяет регулировать другие форматы сжатия (например, Tar) в то же время

Если вы хотите использовать только встроенную поддержку Zip, я хотел бы предложить вам сделать что-то вроде этого:

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

Ваш код потерпит неудачу, как вы пытаетесь читать inner.zip в outer.zip в качестве локального файла, но это Безразлично» t существует как отдельный файл. Код выше будет обрабатывать вещи, оканчивающиеся .zip как другой почтовый файл, и рекурсия

Вы, вероятно, хотите использовать обыкновенный компресс, хотя, так что вы можете обращаться с вещами с альтернативными именами, другие форматами сжатия и т.д.

+0

Это простое решение, но оно не перезаписывается через .RAR. Я пробовал с Tika, но для анализа метаданных требуется довольно много времени (возможно, потому, что он разбирает все это). – ha9u63ar

+0

Я вижу, что я могу заменить ZipInputStream на 'ZipArchiveInputStream', но какой поток я использую для RAR/TAR. Должен ли я хранить «ArchiveInputStream» и «ArchiveEntry» полностью? – ha9u63ar

+0

Если вы хотите работать со всеми форматами с помощью Commons Compress, используйте общие классы архива. Для хорошего примера этого см. [Исходный код парсера пакетов 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

Смежные вопросы