0

我使用下面的代码从 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.
    }
}
4

2 回答 2

0
  • 您应该使用 System.Text.StringBuilder(性能良好)而不是字符串连接(不可变)性能不佳。
  • 您应该使用普通的字符串替换功能,而不是使用复杂的搜索。subDirectory.Name.replace("_", "");
于 2017-02-19T06:16:36.440 回答
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();
}
于 2017-02-21T08:00:54.283 回答