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.
精彩评论