我知道 Oracle 注意到 ZIP/GZIP 文件压缩器/解压缩器方法 on their website .但是我有一个场景,我需要扫描并找出是否涉及任何嵌套的 ZIP/RAR。例如下面的情况:
-MyFiles.zip
-MyNestedFiles.zip
-MyMoreNestedFiles.zip
-MoreProbably.zip
-Other_non_zips
-Other_non_zips
-Other_non_zips
我知道 apache commons 压缩包和 java.util.zip 是广泛使用的包,其中 commons 压缩实际上迎合了 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 的解决方案),但我不确定我是否可以使用元数据按照我想要的方式进行检测。
感谢任何帮助/建议。
最佳答案
使用 Commons Compress 会更容易,尤其是因为它在各种解压器之间有合理的共享接口(interface),这让生活更轻松 + 允许同时处理其他压缩格式(例如 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());
}
}
}
您的代码将失败,因为您尝试将 outer.zip
中的 inner.zip
作为本地文件读取,但它不作为独立文件存在.上面的代码会将以 .zip
结尾的内容作为另一个 zip 文件处理,并将递归
不过你可能想使用 commons compress,这样你就可以处理具有备用文件名、其他压缩格式等的事情
关于用于嵌套 ZIP 文件处理的 Java 实用程序库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35336870/