2011-05-10 36 views
1

我寫遞歸方法來計算文件夾的大小:計算文件夾大小遞歸函數拋出的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:/我得到例外... 也許是因爲我有隱藏的系統目錄,我沒有訪問權限? 您的幫助,將不勝感激。

+0

當某些引用爲空並且您仍然使用它時,您會得到空指針異常。在程序中查看2秒可以清楚地看出,只有值文件或listFiles()的重試值可以爲null。你應該檢查一下。 – Ingo 2011-05-10 18:56:38

+0

你對機器有管理權限嗎?這可能是因爲你要求在沒有權限的目錄上列出文件。只是一個猜測。 – MeBigFatGuy 2011-05-10 19:00:39

+0

MeBigFatGuy,也許你是對的,我有管理員權限,但仍有隱藏文件夾命名爲「系統卷信息」和「$ RECYCLE.BIN」我沒有權利。 – taypen 2011-05-10 19:19:19

回答

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

@taypen找到了錯誤和解決方案+解釋 – JVerstry 2011-05-10 19:32:33

0

這可能是因爲這些目錄裏面沒有任何文件,即你可能會對

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

來自文檔:返回: 一組抽象路徑名,表示由此抽象路徑名錶示的目錄中的文件和目錄。如果目錄爲空,該數組將爲空。如果此抽象路徑名不表示目錄或發生I/O錯誤,則返回null。 – MeBigFatGuy 2011-05-10 18:59:36

+0

我編輯了代碼以顯示出現異常的位置,我在空文件夾中檢查了它,並且它對它們正常工作。 – taypen 2011-05-10 19:02:20

0

越來越NPE試試這個:

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

而且看東西既不是一個文件或目錄。

+0

仍然是異常在同一行,看起來像有空目錄...或類似的東西? – taypen 2011-05-10 19:05:48

1

我不認爲它是file變量必須是null他人同意。我不明白爲什麼listFiles()應該返回一個包含空條目的數組。相反,我認爲dir.listFiles()本身返回null,如果它在非目錄File上調用,它會執行該操作。所以也許你應該嘗試這樣做,只有if dir.isDirectory(),而現在你做它if (!dir.isFile())

UPDATE

好了,把所有在一起是什麼人在這個線程建議,這是有幾個不確定性幾個null檢查片段。

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命中。

+0

我在同一行添加了這個檢查仍NPE。 – taypen 2011-05-10 19:09:23

+0

@taypen - 如果發生I/O錯誤,listFiles()也可能返回null。可能是因爲缺少權限而顯示爲返回空數組的I/O錯誤。基本上,你應該處理返回一個空數組的listFiles()。 – jtahlborn 2011-05-10 19:26:31

+0

他可以檢查listFiles不返回null。順便說一句,@泰恩潘,如何披露NPE發生的行號? – Ingo 2011-05-10 19:28:02

0

從JDK listFiles()返回

抽象路徑 表示文件和目錄中 此抽象 路徑名錶示的目錄的數組。如果 該目錄爲空,則該數組將爲空。如果此抽象路徑名不是 表示目錄或發生I/O錯誤 ,則返回null 。

在調用listFiles()之前檢查dir.exists()和dir.isDirectory(),然後確保它不爲null。