MMasmoudi
MMasmoudi

Reputation: 550

How to differentiate between an empty file that has no extension and a directory in java?

Let's suppose I have a zip file containing two elements: elem1 (created by linux command touch elem1) and elem2 (created by linux command mkdir elem2)

Now, in java, I use the following code to extract the content of the zip

// ...
// Suppose we have a valid inputStream on a zip file
// ...

ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ZipEntry entry = zipInputStream.getNextEntry();

while (entry != null) {
    int entrySize = (int) entry.getSize();
    File file = Paths.get(extractPath).resolve(entry.getName()).toFile();
    if (/*Condition to detect a directory*/) {
        System.out.println("This is a directory");
        FileUtils.forceMkdir(file);
    } else if (/*Condition to detect an empty file*/) {
        System.out.println("This is an empty file");
    } else {
        System.out.println("This is something else");
    }

    entry = zipInputStream.getNextEntry();
}

I would like to specify the right conditions to detect whether entry is a directory, or an empty file without extension. Knowing that these entries are still in memory and do not exist on the filesystem, the command file.isDirectory() always returns false; so I cannot not use it to check for directory.

Any ideas please ?

Upvotes: 0

Views: 220

Answers (1)

hfontanez
hfontanez

Reputation: 6168

I created both an empty folder and an empty file without extension and evaluated them with the code below:

public static void main(String[] args) {
    String path = System.getProperty("user.home") + File.separator + "Desktop" + File.separator;
    File file = new File(path + "EmptyFile");
    File folder = new File (path + "EmptyFolder");
        
    System.out.println("Is 'folder' a folder? " + (Files.isDirectory(folder.toPath())? "Yes" : "No" ));
    System.out.println("Is 'file' a folder? " + (Files.isDirectory(file.toPath())? "Yes" : "No" ));
}

The (not surprising) result:

Is 'folder' a folder? Yes
Is 'file' a folder? No

The reason why this works is because the function Files.isDirectory(...) looks in the file attributes set by the Operating System to determine whether the item being examined is a "File folder" or simply a "file". My assumption is that Zip programs do not contain such metadata (not even Windows zip). Therefore, "isDirectory" test cannot be performed using the Files.isDirectory(...) function. My quick research discovered that, the way to do this (and I am kind of shocked) is by examining the file name and check to see if the name ends with the file separator. In fact, this is how ZipEntry.isDirectory() works.

Attempting to zip an empty folder is not allowed for Windows zip (maybe allowed with other software?). However, I was able to include empty directories with 7-zip. That wasn't the only difference. The isDirectory() test failed when the zip was created with Windows zip because the file was skipped altogether. So, in order for this to work, create the zip file with zip software other than the one that comes with Windows. Then,

public static void main(String[] args) throws IOException {
    String path = System.getProperty("user.home") + File.separator + "Desktop" + File.separator;
    FileInputStream inputStream = new FileInputStream(path + "Desktop.zip");
    ZipInputStream zipInputStream = new ZipInputStream(inputStream);
    ZipEntry entry = zipInputStream.getNextEntry();

    while (entry != null) {
        File file = Paths.get(entry.getName()).toFile();
            
        if (entry.isDirectory()) {
            System.out.println(entry.getName() + " is a directory");
        } else if (file.getName().endsWith(".lnk")) {
            System.out.println(file.getName() + " is a shortcut");
        } else {
            System.out.println(entry.getName() + " is a file");
        }
            entry = zipInputStream.getNextEntry();
    }
    zipInputStream.close();
}

Outputs for me:

EmptyFile is a file
EmptyFolder/ is a directory
How We Test Wireless Routers _ PCMag_files/ is a directory
How We Test Wireless Routers _ PCMag_files/00hSyhn9j5PNrcOot1tMzz9.1578945749.fit_lim.size_100x100.png is a file
...
etc

One last note... obviously, if a ZipEntry is not a directory, it is a file. Therefore, no else if is needed. That is, unless you would like to make a distinction between file types. In the example above, I wanted to check if a particular file was a shortcut. Just keep in mind that this is not necessary. The logic should only test entries for isDirectory and if the test fails, it is simply a file.

Upvotes: 2

Related Questions