计算文件夹大小的递归函数抛出NullPointerException(Java)

时间:2011-05-10 18:52:20

标签: 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()) {
        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:/我得到例外...... 也许是因为我有隐藏的系统目录,我没有访问权限? 感谢您的帮助。

5 个答案:

答案 0 :(得分:1)

有人可能在平均时间内删除了文件'(即,在递归期间)。

您可以添加测试,例如:

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

答案 1 :(得分:1)

我不同意其他人认为file变量必须是null。我不明白为什么listFiles()应该返回一个包含空条目的数组。相反,我认为dir.listFiles()本身会返回null,如果在非目录File上调用它,它就会返回null。所以也许你应该尝试只做if dir.isDirectory(),而现在你做if (!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的位置。

答案 2 :(得分:0)

可能是因为这些目录中没有文件,即您可能会在

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

答案 3 :(得分:0)

试试这个:

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

看看某些东西既不是文件也不是目录。

答案 4 :(得分:0)

来自JDK listFiles()返回

  

一组抽象路径名   表示文件和目录   此摘要表示的目录   路径名。如果,该数组将为空   目录为空。返回null   如果这个抽象路径名没有   表示目录,或者是否为I / O错误   发生。

在调用listFiles()之前检查是否有dir.exists()和dir.isDirectory(),然后确保它不为null。