开发者

Recursive function that calculates folder size throws NullPointerException (Java)

I wrote recursive method to calculate folder size:

    private static long calcSize(File dir) {
    if (dir.isFile() && dir.canRead()) {
        return dir.length();
    }
    long size = 0;
    if ( dir.exists() && dir.isDirectory() && dir.canRead()) {
        for (File file : dir.listFiles()) { //Here NPE
            if (file.isFile()  && dir.canRead())
                size += file.length();
            else if (file.isDirect开发者_高级运维ory())
                size += calcSize(file);
            else
                throw new Error("What is this: " + file);
        }
    }
    return size;
}

added additional checks as users advised. still getting NPE.

NPE occurs when executing:

calcSize(new File("D:/"))

on another folders it works fine. but on D:/ and C:/ i get the exception... Maybe its because i have hidden system directories on which i have no access rights? Your help would be appreciated.


Someone may have deleted the File 'in the mean time' (i.e., during recursivity).

You could add a test, something like:

if ( dir.exists() ) {
   ...
}

EDIT - FOUND THE ERROR AND THE SOLUTION

I could replicate it. The program crashes when it loops on Recycle Bin objects. In fact, dir.listFiles() returns null in that case.

You need to update your method like this and it works:

        long size = 0;
        System.out.println(dir.toString());
        File[] tmp = dir.listFiles();
        if ( tmp != null ) {
            for (File file : dir.listFiles()) { // NPE gone
                if (file.isFile())
                    size += file.length();
                else
                    size += calcSize(file);
            }
        }


I don't agree with the others that it's the file variable that has to be null. I don't see why listFiles() should return an array which contains null entries. Rather, I think dir.listFiles() itself returns the null, which it does if it is called on a non-directory File. So perhaps you should try to do that only if dir.isDirectory(), whereas now you do it if (!dir.isFile()).

UPDATE

Ok, putting all together what the people have suggested in this thread, this is a snippet which has several null checks for the several uncertainties.

private static long calcSize(File dir) {
    if (dir == null) return 0;
    if (dir.isFile()) return dir.length();
    if (!dir.isDirectory()) return 0;

    File[] files = dir.listFiles();
    if (files == null) return 0;

    long size = 0;
    for (File file : files) {
        if (file == null) continue;
        if (file.isFile())
            size += file.length();
        else
            size += calcSize(file);
    }

    return size;
}

See if this works for you, and if you are still interested, you can one remove one safety net at a time to see where the NPE hits.


It might be because there is no files inside these directories ie you might be getting NPE at

for (File file : dir.listFiles()) {
            if (file.isFile()) //here NPE
                size += file.length();
            else
                size += calcSize(file);
        }


Try this:

if (file.isFile())
    size += file.length();
else if (file.isDirectory())
    size += calcSize(file);
else
    throw new Error("What is this: " + file);

And see if something is neither a file or a directory.


From JDK listFiles() returns

An array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname. The array will be empty if the directory is empty. Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs.

Check to see if dir.exists() and dir.isDirectory() before calling listFiles() and then ensure it is not null.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜