Emma
Emma

Reputation: 57

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:

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)

Upvotes: 3

Views: 8979

Answers (2)

Kaj Wortel
Kaj Wortel

Reputation: 71

Perhaps a bit late, but for those who are still looking for a nice way of solving this, here is my answer.

The method (grepCode):

public boolean isDirectory() {
    return name.endsWith("/");
}

where name is the same value returned by ZipEntry.getName().

For Windows systems, for example, this should be "\\", hence ZipEntry.isDirectory will always return false. To solve this you can use:

ze.getName().endsWith(File.separator)

instead of

ze.isDirectory()

Upvotes: 3

Emma
Emma

Reputation: 57

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

}

Upvotes: 1

Related Questions