简体   繁体   中英

How to get a size of a image file which is inside a folder which is inside a zip file

I have the following snippet and this is used to check if the given zip entry is a directory or not which works fine.There is an additional requirement given where I need to check the size of each image (its size should not be > 10 MB) inside the folder which is inside the zip file. I been going through some articles but couldn't get hold of a scenario similar to mine.

The example structure for a zip file would look like the one given below along with the folder and the images size inside them

XYZ.zip>023423>Bat1.jpg ->11MB 
XYZ.zip>023423>Bat2.jpg ->5MB 
XYZ.zip>023423>Bat3.jpg ->11MB
XYZ.zip>023423>Bat4.jpg ->10MB

Based on the scenario above, at the end of the execution I should able to get the Bat1 & Bat3 as output as their size is >10 MB.Kindly advise.

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

As mentioned in the comments, the value of getSize is not set when reading from a ZipInputStream - unlike when using ZipFile . However you could try to scan the stream contents yourself and monitor the sizes of each entry.

This method scans any ZIP passed in as InputStream which could be derived from a file or other downloaded source:

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

This approach is not ideal for very large ZIP content, but it may be worth trying for your specific case - better to have a slow solution than none at all.

If there are really big entries in the ZIP you might also consider replacing the line long size = zis.transferTo(bout); with a call to your own method which does not transfer content but still returns the size - similar to implementation of InputStream.transferTo but commenting out the write() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM