问题描述
我有以下代码段,它用于检查给定的 zip 条目是否是一个工作正常的目录。还有一个额外的要求,我需要检查每个图像的大小(它的大小不应该是> 10 MB)在 zip 文件内的文件夹中。 我浏览了一些文章,但找不到与我相似的场景。
XYZ.zip>023423>Bat1.jpg ->11MB
XYZ.zip>023423>Bat2.jpg ->5MB
XYZ.zip>023423>Bat3.jpg ->11MB
XYZ.zip>023423>Bat4.jpg ->10MB
基于上面的场景,在执行结束时,我应该能够将 Bat1 和 Bat3 作为输出,因为它们的大小 > 10 MB。请告知。
private void isgivenZipInFolderStructure(ExcelImportCronJobModel
cronJob) {
try {
foldersInZip = new ArrayList<>();
if(cronJob.getReferencedContent() !=null) {
final ZipInputStream zip = new ZipInputStream(this.mediaService.getStreamFromMedia(cronJob.getReferencedContent()));
ZipEntry entry = null;
while ((entry = zip.getNextEntry()) != null) {
LOG.info("Size of the entry {}",entry.getSize());
if(entry.isDirectory()) {
foldersInZip.add(entry.getName().split(BunningscoreConstants.FORWARD_SLASH)[0]);
}
}
}
} catch (IOException e) {
LOG.error("Error reading zip,e");
}
}
解决方法
如评论中所述,从 getSize
读取时未设置 ZipInputStream
的值 - 与使用 ZipFile
时不同。但是,您可以尝试自己扫描流内容并监控每个条目的大小。
此方法扫描作为 InputStream 传入的任何 ZIP,这些 ZIP 可以从文件或其他下载源派生:
public static void scan(InputStream is) throws IOException {
System.out.println("==== scanning "+is);
ZipEntry ze;
// Uses ByteArrayOutputStream to determine the size of the entry
ByteArrayOutputStream bout = new ByteArrayOutputStream();
long maxSize = 10_000_000L;
try (ZipInputStream zis = new ZipInputStream(is)) {
while ((ze = zis.getNextEntry()) != null) {
bout.reset();
long size = zis.transferTo(bout);
System.out.println(ze.getName()
+(ze.isDirectory() ? " DIR" : " FILE["+size+"]")
+(size > maxSize ? " *** TOO BIG ***":"")
);
if (size > maxSize) {
// entry which is too big - do something / warning ...
} // else use content: byte[] content = bout.toByteArray();
}
}
}
这种方法对于非常大的 ZIP 内容并不理想,但对于您的特定情况可能值得尝试 - 有一个缓慢的解决方案总比没有好。
如果 ZIP 中确实有很大的条目,您还可以考虑将行 long size = zis.transferTo(bout);
替换为对您自己的方法的调用,该方法不会传输内容但仍会返回大小 - 类似于 {{1} 的实现} 但注释掉 InputStream.transferTo
。