【问题标题】:Recursive Directory Structure Listing Taking To Long To Process递归目录结构列表需要很长时间才能处理
【发布时间】:2013-02-20 13:17:44
【问题描述】:

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

【问题讨论】:

  • 您的用户是否必须一次查看所有展开的项目?当用户点击结构时,为什么不按需获取文件夹?
  • 您的大部分性能损失可能会出现在磁盘 I/O 中。
  • @Alex 我该怎么做,C# + ASP.NET 对我来说是新手,我是一名 Java 认证助理,仍在学习 C# + ASP.NET 的所有方面。跨度>
  • @Lloyd 这个应用程序在数据中心的一台价值 3 万美元的服务器上运行,我为一家大公司工作。我认为我不必担心 I/O,因为服务器已从运行企业级闪存盘(企业级 SSD)的 EMC(2) 分配到 SAN 上的 lund。
  • @Alex 我会使用非递归代码,只是查看是否有子目录,然后单击导航到另一个路径,例如显示 C:\First,当他们单击 First\Second 时导航到index.aspx?path=C:\First\Second ?

标签: c# asp.net directoryinfo


【解决方案1】:
  • 您应该使用 System.Text.StringBuilder(性能良好)而不是字符串连接(不可变)性能不佳。
  • 您应该使用普通字符串替换功能而不是使用复杂搜索。 subDirectory.Name.replace("_", " ");

【讨论】:

    【解决方案2】:

    代码运行缓慢的主要原因很可能是多次调用 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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-14
      • 1970-01-01
      • 2014-11-10
      • 1970-01-01
      • 1970-01-01
      • 2020-05-27
      • 1970-01-01
      相关资源
      最近更新 更多