Search code examples
javaunzipdirectory-structure

Discovering whether a ZipEntry is a Directory or Not using isDirectory()


I had planned to use ZipEntry's isDirectory() method to identify whether a zip file contained a directory when validating the file structure of the zip file.

The zip files should have the following file structure: - content/file1.pdf - afile.xml - anotherfile.xml

Every zip file must have a folder which must contain some content. I would like to have been able to rely on isDirectory() to check if there is a directory, for example:

//this is part of a unit test which checks the structure of zipped file.
public List<String> unzip(String outpath) { 
    List<String> fnames = new ArrayList<String>();
    try  { 
        FileInputStream fin = new FileInputStream(outpath); 
        ZipInputStream zin = new ZipInputStream(fin); 
        ZipEntry ze = null; 
        boolean contentFound = false; 

        while ((ze = zin.getNextEntry()) != null) { 

            if(ze.isDirectory()) {  
                contentFound = true; 
            } 
            else { 
                fnames.add(ze.getName());
                zin.closeEntry(); 
            }          
        } 
        zin.close(); 
        assertTrue("Content folder not found", contentFound);
    } catch(Exception e) { 
    } 
    return fnames;
} 

When isDirectory() was never true despite providing a zip file which contained the content directory, I used the following to see what was being picked up:

public List<String> unzip(String outpath) { 
    List<String> fnames = new ArrayList<String>();
    try  { 
        FileInputStream fin = new FileInputStream(outpath); 
        ZipInputStream zin = new ZipInputStream(fin); 
        ZipEntry ze = null; 
        boolean contentFound = false; 

        while ((ze = zin.getNextEntry()) != null) { 
            System.out.println(ze.getName());
            fnames.add(ze.getName());
            zin.closeEntry();     
        } 
        zin.close(); 
        assertTrue("Content folder not found", contentFound);
    } catch(Exception e) { 
    } 
    return fnames;
}  

Output for this is:

  • content/file2.pdf
  • content/file1.pdf
  • anotherfile.xml
  • file.xml

I think isDirectory() is never evaluating to be true because the path "content/file2.pdf" is pointing to a file which is contained in the directory and not to the directory itself. I'm not sure what I have to do to identify the directory on its own using isDirectory(). While I have a work around for this problem I would rather understand why isDirectory() didn't work as I expect that I might be approaching the problem wrong.

The work around for identifying the presence of the folder which is:

if (zipEntry.getName().contains("content/")) {
currentJob.contentFolderFound();
...

(Note: Credit where credit is due, the original unzip method was derived from this solution: Read all files in a folder)


Solution

  • While refactoring the method from where this question came from I have managed to get isDirectory() to evaluate as true when zipEntry is the folder itself (yey!)

    I was refactoring while referencing the following guide: http://www.mkyong.com/java/how-to-decompress-files-from-a-zip-file/

    It seems that the confusion was from creating ZipEntry within the while (unless you can see any other difference)

        ZipInputStream zis;
        ZipEntry zipEntry;
        try {
            zis = new ZipInputStream(filePart.getInputStream());
            zipEntry = zis.getNextEntry(); 
        } catch (IOException ioExc) {
            //do something;
        }
    while(zipEntry != null){ //if you run me I will infinitely loop!
        String fileName = zipEntry.getName();
        System.out.println("I am the directory! " +zipEntry.isDirectory() + " " + zipEntry.getName());
    
    }