用于嵌套ZIP文件处理的Java实用程序库

ha9*_*3ar 7 java recursion zip apache-commons-compress apache-tika

我知道Oracle 在其网站上注明了ZIP/GZIP文件压缩器/解压缩器方法.但我有一个场景,我需要扫描并找出是否涉及任何嵌套的ZIP/RAR.例如,以下情况:

-MyFiles.zip
   -MyNestedFiles.zip
        -MyMoreNestedFiles.zip
           -MoreProbably.zip
        -Other_non_zips
   -Other_non_zips
-Other_non_zips
Run Code Online (Sandbox Code Playgroud)

我知道apache commons压缩包和java.util.zip是广泛使用的包,其中commons压缩实际上迎合了java.util.zip中缺少的功能,例如在进行压缩时的一些字符设置.但我不确定的是通过嵌套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();
        }
    }  
Run Code Online (Sandbox Code Playgroud)

可能是我做错了 - 或使用了错误的工具.我的目标是确定是否有任何文件或嵌套的zip文件有我不允许的文件扩展名.这是为了确保我可以阻止我的用户上传禁止的文件,即使他们正在压缩它.我也可以选择使用可以进行递归解析的Tika(使用Zukka Zitting的解决方案),但我不确定我是否可以使用元数据来执行此检测.

任何帮助/建议表示赞赏.

Gag*_*arr 4

使用 Commons Compress 会更容易,尤其是因为它在各种解压缩器之间具有合理的共享接口,这使生活更轻松+允许同时处理其他压缩格式(例如 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());
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

当您尝试将其作为本地文件读取时,您的代码将失败inner.zipouter.zip但它并不作为独立文件存在。上面的代码将处理以.zip另一个 zip 文件结尾的内容,并将递归

不过,您可能想使用公共压缩,这样您就可以使用备用文件名、其他压缩格式等来处理事情