1

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.isDirectory())
                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.

3
  • You get a null pointer exception when some reference is null and you use it nevertheless. Looking 2 secs at the program makes it clear that only the value file or the retrun value of listFiles() could be null. You ought to check for that. Commented May 10, 2011 at 18:56
  • Do you have admin rights on the machine? It might be that you ask to listFiles on a directory that you have no rights too. Just a guess. Commented May 10, 2011 at 19:00
  • MeBigFatGuy, maybe you right, I got admin rights but there are still hidden folders named "System Volume Information" and "$RECYCLE.BIN" on which i have no rights. Commented May 10, 2011 at 19:19

5 Answers 5

1

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);
            }
        }
Sign up to request clarification or add additional context in comments.

Comments

1

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.

4 Comments

i added this check still NPE at the same line.
@taypen - listFiles() may also return null if an I/O error occurs. it may be that the lack of permissions is manifesting as an I/O error which is returning a null array. basically, you should handle listFiles() returning a null array.
He could just check that listFiles does not return null. BTW, @taypen, how about disclosing the line number the NPE occurs?
Correct. From JDK "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."
0

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

2 Comments

from the docs: 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.
i edited the code to show where i get the exception, i checked it on empty folders and it works fine on them.
0

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.

1 Comment

still exception at the same line, looks like there are null directories... or something like that?
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.