如何获取位于 zip 文件内的文件夹内的图像文件的大小

问题描述

我有以下代码段,它用于检查给定的 zip 条目是否是一个工作正常的目录。还有一个额外的要求,我需要检查每个图像的大小(它的大小不应该是> 10 MB)在 zip 文件内的文件夹中。 我浏览了一些文章,但找不到与我相似的场景。

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