2013-05-11 75 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