计算文件夹大小的递归函数抛出NullPointerException(Java)
我编写了递归方法来计算文件夹大小:计算文件夹大小的递归函数抛出NullPointerException(Java),java,recursion,io,nullpointerexception,Java,Recursion,Io,Nullpointerexception,我编写了递归方法来计算文件夹大小: private static long calcSize(File dir) { if (dir.isFile() && dir.canRead()) { return dir.length(); } long size = 0; if ( dir.exists() && dir.isDirectory() && dir.canRead()) {
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;
}
根据用户建议添加了额外的检查。仍然得到NPE
执行以下操作时发生NPE:
calcSize(new File("D:/"))
在另一个文件夹上,它可以正常工作。但在D:/和C:/上,我得到了一个例外。。。
可能是因为我有隐藏的系统目录,我没有访问权限?
非常感谢您的帮助。这可能是因为这些目录中没有文件,即您可能正在获取NPE
for (File file : dir.listFiles()) {
if (file.isFile()) //here NPE
size += file.length();
else
size += calcSize(file);
}
试试这个:
if (file.isFile())
size += file.length();
else if (file.isDirectory())
size += calcSize(file);
else
throw new Error("What is this: " + file);
然后查看某个内容是否既不是文件也不是目录。可能有人“同时”(即在递归过程中)删除了该文件 您可以添加一个测试,例如:
if ( dir.exists() ) {
...
}
编辑-找到错误和解决方案
我可以复制它。程序在回收站对象上循环时崩溃。实际上,在这种情况下,dir.listFiles()返回null
您需要像这样更新您的方法,它可以工作:
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);
}
}
我不同意其他人的观点,即
文件
变量必须为null
。我不明白为什么listFiles()
应该返回一个包含空条目的数组。相反,我认为dir.listFiles()
本身返回空值,如果在非目录文件
上调用它就会返回空值。因此,如果dir.isDirectory(),那么您可能应该尝试只执行操作,而现在如果(!dir.isFile())
则执行操作
更新
好的,把人们在这个线程中的建议放在一起,这是一个片段,它对几个不确定性进行了一些空检查
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;
}
看看这是否对您有效,如果您仍然感兴趣,您可以一次移除一个安全网,以查看NPE的位置。来自JDKlistFiles()
返回
抽象路径名数组
表示中的文件和目录
此摘要表示的目录
路径名。如果
目录为空。返回空值
如果此抽象路径名不存在
表示目录,或者如果出现I/O错误
发生
在调用listFiles()之前,请检查dir.exists()和dir.isDirectory()是否存在,然后确保它不为null。当某个引用为null时,会出现null指针异常,并且仍然使用它。查看该程序2秒钟可以清楚地看出,只有值file或listFiles()的retrun值可以为null。你应该检查一下。你有这台机器的管理员权限吗?可能是您要求在您没有权限的目录上列出文件。只是猜测一下。MeBigFatGuy,也许你是对的,我有管理员权限,但仍有名为“系统卷信息”和“$RECYCLE.BIN”的隐藏文件夹,我对此没有权限。从文档:返回:一个抽象路径名数组,表示此抽象路径名表示的目录中的文件和目录。如果目录为空,则数组将为空。如果此抽象路径名不表示目录,或者发生I/O错误,则返回null。我编辑了代码以显示从何处获取异常,我在空文件夹上检查了异常,并且在空文件夹上正常工作。在同一行仍然存在异常,看起来有空目录。。。或者类似的东西?我在同一行添加了这个检查仍然是NPE。@如果发生i/O错误,taypen-listFiles()也可能返回null。权限的缺乏可能表现为I/O错误,返回空数组。基本上,您应该处理listFiles()返回空数组的问题。他可以检查listFiles是否不返回空数组。顺便说一句,@taypen,披露NPE发生的行号如何?正确。来自JDK“一个抽象路径名数组,表示此抽象路径名表示的目录中的文件和目录。如果目录为空,则该数组为空。如果此抽象路径名不表示目录,或者如果发生I/O错误,则返回null。”