递归目录结构列表需要长时间处理

时间:2013-02-20 13:17:44

标签: c# asp.net directoryinfo

我使用下面的代码从GET变量提供的路径(根)开始,并递归进入每个子文件夹并将其内容显示为列表项。我使用的路径有大约3800个文件和375个子文件夹。我需要大约45秒来渲染页面,有没有办法可以减少这个时间,因为这对我的用户来说是不可接受的。

string output;
protected void Page_Load(object sender, EventArgs e) {
    getDirectoryTree(Request.QueryString["path"]);
    itemWrapper.InnerHtml = output;
}

private void getDirectoryTree(string dirPath) {
    try {
        System.IO.DirectoryInfo rootDirectory = new System.IO.DirectoryInfo(dirPath);
        foreach (System.IO.DirectoryInfo subDirectory in rootDirectory.GetDirectories()) {
            output = output + "<ul><li><a>" + Regex.Replace(subDirectory.Name, "_", " ");
            if (subDirectory.GetFiles().Length != 0 || subDirectory.GetDirectories().Length != 0) {
                output = output + " +</a>";
            } else {
                output = output + "</a>";
            }
            getDirectoryTree(subDirectory.FullName);
            if (subDirectory.GetFiles().Length != 0) {
                output = output + "<ul>";
                foreach (System.IO.FileInfo file in subDirectory.GetFiles()) {
                    output = output + "<li><a href='" + file.FullName + "'>" + file.Name + "</a></li>";
                }
                output = output + "</ul>";
            }
            output = output + "</li></ul>";
        }
    } catch (System.UnauthorizedAccessException) {
        //This throws when we don't have access.
    }
}

2 个答案:

答案 0 :(得分:0)

  • 您应该使用System.Text.StringBuilder(性能良好)而不是字符串连接(不可变)性能不佳。
  • 你应该使用普通的字符串替换功能,不使用复杂的搜索。 subDirectory.Name.replace(&#34; _&#34;,&#34;&#34;);

答案 1 :(得分:0)

代码缓慢的主要原因很可能是对GetFiles和GetDirectories的多次调用。您是在if条件以及初始查找中一遍又一遍地调用它们。您只需要一次计数。此外,添加字符串并不能帮助解决问题。

以下代码能够在300毫秒内通过我的简单usb驱动器运行,并返回400多个文件夹和11000个文件。在慢速网络驱动器上,它可以在9秒内返回300个文件夹中的4000个文件。在递归期间,可以使用Parallel.ForEach进一步优化它。

protected void Page_Load(object sender, EventArgs e) {

    itemWrapper.InnerHtml = GetDirectory(Request.QueryString["path"]);
}

static string GetDirectory(string path)
{
    StringBuilder output = new StringBuilder();
    var subdir = System.IO.Directory.GetDirectories(path);
    var files = System.IO.Directory.GetFiles(path);
    output.Append("<ul><li><a>");
    output.Append(path.Replace("_", " "));
    output.Append(subdir.Length > 0 || files.Length > 0 ? "+</a>" : "</a>");

    foreach(var sb in subdir)
    {
        output.Append(GetDirectory(sb));
    }

    if (files.Length > 0)
    {
        output.Append("<ul>");
        foreach (var file in files)
        {
            output.AppendFormat("<li><a href =\"{0}\">{1}</a></li>", file, System.IO.Path.GetFileName(file));
        }
        output.Append("</ul>");
    }
    output.Append("</ul>");
    return output.ToString();
}