2013-05-11 73 views
0

我有一個函數,加載給定的文件夾中的所有* .txt和所有它的子文件夾。我想獲得實際的進展(例如15/35加載)。如何在遞歸爬取目錄結構時取得進展?

但我想不出如何獲得加載到目錄下一級目錄結構的文件數目,以添加到當前索引。

* a 
    * b 
    - 1.txt (file in dir b) 
    - 1.txt (file in dir a) 
    - 2.txt _(index of this file is 3 - one file from dir below, one file in this dir)_ 

代碼:

public int getFilesInSubfolders(directory) 
    { 
     int count = 0; 

     foreach (subdirectory in directory) 
     { 
      count += getFilesInSubfolders(); 
     } 

     foreach (txtfile in folderFiles) 
     { 

      load(txtfile); 
      count++; 

      updateProgress(actualIndex); // how to get the actual index? e.g. 15/35 loaded, so that 15 
     } 
     return count; 
    } 
+0

這是一個雞與雞蛋的問題。記錄你上次找到多少個文件,這是下一次的事。 – 2013-05-11 18:10:02

回答

2

有解決這個問題的方法有兩種。

您可以將ref int count傳遞給每個遞歸調用。最外面的呼叫將初始化爲count爲零。

例如:

public int IterateDirectories(string root) 
{ 
    int count = 0; 
    iterateDirectories(root, ref count); 
    return count; 
} 

private void iterateDirectories(string root, ref int count) 
{ 
    foreach (string directory in Directory.EnumerateDirectories(root)) 
     iterateDirectories(directory, ref count); 

    foreach (string file in Directory.EnumerateFiles(root, "*.txt")) 
    { 
     // load(file); 

     ++count; 

     // Now count is the actual number of files processed, 
     // so you can use it for updateProgress() 
    } 
} 

或者,你可以用整個事情中的一類這樣的:

public sealed class DirectoryIterator 
{ 
    public static int Iterate(string root) 
    { 
     var iterator = new DirectoryIterator(); 
     iterator.iterate(root); 
     return iterator.count; 
    } 

    private void iterate(string root) 
    { 
     foreach (string directory in Directory.EnumerateDirectories(root)) 
      iterate(directory); 

     foreach (string file in Directory.EnumerateFiles(root, "*.txt")) 
     { 
      // load(file); 

      ++count; 

      // Now count is the actual number of files processed, 
      // so you can use it for updateProgress() 
     } 
    } 

    private int count; 

    private DirectoryIterator(){} 
} 

您可以使用這樣的:

int count = DirectoryIterator.Iterate("D:\\"); 

(雖然你可能不在乎關於返回的值)。

您需要修改此代碼以確切目的(它沒有計算您已經計算的文件的總數,因此您必須添加一個字段以用於那)。

注:我已經從這兩個例子中省略了錯誤處理。真正的代碼必須避免受保護的系統目錄。

+0

謝謝!我從來沒有聽說過裁判,但它創造了一天。我已經完成了所有例外檢查並計算了以前的文件總數。我只是忽略這些以顯示真正的問題。 – 2013-05-11 18:48:38

0

我不明白你爲什麼要使用遞歸此。還有就是Directory.GetFiles方便的過載,讓您獲得所有子文件夾中的所有文件:

public int GetFilesInSubfolders(string directory) 
{ 
    var files = Directory.GetFiles(directory, "*.txt", SearchOption.AllDirectories)); 
    for (var i = 0; i < files.Length; i++) 
    { 
     load(files[i]); 
     updateProgress(i); 
    } 

    return files.Length; 
} 
+0

SearchOption。由於系統權限,即使所有文件夾中有一個文件夾試圖訪問時,AllDirectories也無法加載任何文件,導致整個過程崩潰。 – 2013-05-11 17:42:07

0

明顯簡單的解決辦法是循環兩次 - 第一次計數的文件數量,然後使用計數器updateProgress。 爲了使其更具可讀性,您可以使用Stack<T>數據結構將其重構爲遠離遞歸,但這是另一回事。

確定您的解釋後,我承擔以下重構。 只要不使用遞歸,就有actualIndex

int totalCounter = GetTheTotalTxtFilesNumber();//as you've mentioned you already have it 

Stack<Directory> directoryStack = new Stack<Directory>(); 
    directoryStack.Push(directory); 

    int actualIndex = 0; 
    while(directoryStack.Count > 0) 
    { 
    Dirextory current = directoryStack.Pop(); 

    foreach (txtfile in folderFiles) 
    { 
     load(txtfile); 
     actualIndex++; 
     updateProgress(actualIndex);//15 out of 35 
    } 
    foreach (subdirectory in current) 
    { 
     directoryStack.Push(subdirectory); 
    } 
    } 
+0

你是什麼意思循環兩次?我不需要獲取文件的總數,我已經擁有了它(之前再循環一次)。我只需要在整個文件加載過程中獲得ACTUAL/CURRENT-PROCESSED文件索引。 – 2013-05-11 17:49:15

+0

@JoudicekJouda檢查我的編輯,看起來像我已經瞭解你 – 2013-05-11 18:34:27

0

我可以給你15/35中的15個部分,但不是35部分,因爲我不知道,直到這個迭代完成爲止。

公衆詮釋getFilesInSubfolders(目錄,詮釋計數){

foreach (subdirectory in directory) 
    { 
     getFilesInSubfolders(subDirectory,count); 
    } 

    foreach (txtfile in folderFiles) 
    { 

     load(txtfile); 
     count++; 

     updateProgress(count); // how to get the actual index? e.g. 15/35 loaded, so that 15 
    } 
    return count; 
} 
+0

我已經有了一個。 15部分是我所需要的,但問題是,您的解決方案不起作用(我在發佈之前已經嘗試過)。它爲您提供當前目錄中的計數,但是當向上推進一個目錄時,它將從零開始計數。因此,如果有35個文件分佈在7個文件夾中,每個文件5個文件,則會給出(1,2,3,4,5,1,2,3,4,5,...)7次。試試吧,我自己也不相信.. – 2013-05-11 18:01:10