【问题标题】:Java program to calculate directory size keeps throwing NPE计算目录大小的Java程序不断抛出NPE
【发布时间】:2013-11-14 02:01:02
【问题描述】:

我正在开发一个循环特定目录(例如 C:\Documents)并计算它在磁盘上占用的总大小的程序。但是,由于某种原因,我的程序在似乎在 Documents 文件夹中查找名为“My Music”的文件夹时不断抛出空指针异常。 “我的音乐”在我的 Documents 文件夹中不存在,所以我很困惑它从哪里获取。我理解它为什么会抛出异常(显然,如果它在指定目录中找不到文件夹,它将返回 null),但我不知道它是如何找到“我的音乐”的。这是我的代码:

public static Long getDirSize(File directory) {
    long size = 0L;
    for (File file : directory.listFiles()) {
        size += file.isDirectory() ? getDirSize(file) : file.length();
    }
    return size;
}

要调用此方法,我使用以下代码:

long required = 0;
for (int i = 0; i < directories.length; i++){
required = required + getDirSize(new File(directories[i]));

"directories" 是一个字符串数组,其中包含我要计算其大小的目录。例如, 目录 = {"C:\Users\user\Documents", "C:\用户\用户\图片", "C:\Users\user\Videos"}

我已经尝试解决这个问题好几个星期了,尝试不同的方法来遍历目录等,它们似乎都给了我同样的问题。我将非常感谢另一组对此的看法。谢谢!

编辑:这是堆栈跟踪--

java.lang.NullPointerException
at diana.Review.getDirSize(Review.java:206)
at diana.Review.getDirSize(Review.java:207)
at diana.Review$2.actionPerformed(Review.java:126)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

【问题讨论】:

  • 代码看起来不错,你能发布你的堆栈跟踪吗?
  • 让我猜猜。您使用的是 Windows Viste 还是更高版本?在这种情况下,MyDocuments 是一个 Junction(我认为它们仍然没有迁移到符号链接,尽管 NTFS 现在支持它们),而 Java 似乎无法处理 NTFS 文件系统上的那些。
  • @user2310289 Stacktrace 已添加。
  • @Johannes H,你说得对——我在 Windows 8 上。
  • @JohannesH.,在这种情况下,我之前没有听说过“Junction”这个词。在这种情况下是什么意思?

标签: java size directory


【解决方案1】:

我会在实际使用之前尝试测试该文件。我会做类似于if(file != null)if(file.exists()) 的事情。这样,如果文件不存在,您就不会尝试使用它。这应该可以解决您遇到错误的问题。

此外,按照 Windows 的工作方式,在您的“我的文档”目录中,默认情况下有一个名为“音乐”的文件夹,但根据您在资源管理器中的访问位置,它可能会显示“我的音乐”或“用户的音乐”。我不知道为什么会发生这种情况,但出于某种原因确实如此。

因此,防止出现此错误的基本万无一失的方法是检查您要使用的文件是否存在。如果没有,请跳过它或打印错误消息。希望这可以帮助。

【讨论】:

  • 我可以告诉你为什么资源管理器列出不同的名称:它位于名为“desktop.ini”的隐藏文件中。丑陋的黑客正确的本地化,混淆了“高级用户”,他们实际上需要知道如何在 Windows 资源管理器之外访问目录,并造成比它解决的更多的麻烦。必须处理 Windows 系统时,我做的第一件事就是删除这些条目。
  • 啊,原来如此。感谢您的洞察力。
  • “音乐”或“我的音乐”或“用户音乐”文件夹直接位于我的 C 盘中,与“文档”(也称为“我的文档”)完全分开。似乎当它完成对 Documents 中现有文件夹的循环时,它退出 Documents 目录并进入 C 目录,并查看下一个文件夹(我的音乐),但它仍然在文档目录中查找它。我不知道这是否有意义....
【解决方案2】:

listFiles() 可以返回 null。请参阅 Javadoc。您需要在循环之前对此进行测试。这意味着您不能在其上使用增强的 for 循环。

【讨论】:

  • 我想我尝试进行检查以确保它不是 null 一次,但遇到了这个问题。你会建议我如何修改它以避免这个问题?
  • 在我看来,我已经回答过了,除非你要求被灌输代码。
  • 抱歉,这不是我的本意。我试图弄清楚如何在没有增强的 for 循环的情况下遍历目录,以一种允许我每次检查 listFiles() 是否为空的方式。在我看来,这本身就需要循环。我不要求代码,我只是想指出正确的方向
  • 您不必每次都检查 isFiles() 是否返回 null。您只需检查一次,循环。
  • 非常感谢您对 EJP 的帮助。我想每次都必须检查。我在方法开始时进行了检查,现在似乎一切正常。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 1970-01-01
  • 2017-02-06
  • 1970-01-01
  • 2022-01-12
  • 2010-11-26
相关资源
最近更新 更多