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

4 回答 4

2

有两种方法可以解决这个问题。

您可以将 a 传递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:\\");

(尽管您可能不关心返回值。)

您需要根据您的确切目的修改此代码(它没有您说您已经计算过的文件总数,因此您必须为此添加一个字段)。

注意:我在这两个示例中都省略了错误处理。真正的代码必须避开受保护的系统目录。

于 2013-05-11T18:18:40.043 回答
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;
}
于 2013-05-11T17:36:14.227 回答
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 );
    }
  }
于 2013-05-11T17:41:50.200 回答
0

我可以给你 15/35 的 15 部分,但不能给你 35 部分,因为我不知道,直到迭代完成。

公共 int getFilesInSubfolders(目录,int 计数){

    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;
}
于 2013-05-11T17:50:09.877 回答