2013-02-20 3 views
0

Я использую следующий код, начинающийся с пути (root), предоставляемого переменной 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. 
    } 
} 
+0

Ваши пользователи должны видеть все расширенные предметы одновременно? Почему бы вам не получить папки по требованию, когда пользователь нажимает на эту структуру? – Alex

+0

Большая часть вашего удара по производительности будет, вероятно, в дисковой операции ввода-вывода. – Lloyd

+0

@Alex Как я могу это сделать, C# + ASP.NET для меня новичок, я сертифицированный Java-помощник, все еще изучая все аспекты C# + ASP.NET. –

ответ

0
  • Вы должны использовать System.Text.StringBuilder (хорошая производительность) вместо строки конкатенации (непреложных) Плохой производительности.
  • Вы должны использовать обычную функцию замены строки, не используя сложный поиск. subDirectory.Name.replace ("_", "");
0

Основная причина медленности вашего кода - это, скорее всего, несколько вызовов GetFiles и GetDirectories. Вы вызываете их снова и снова в if условиях, а также в ваших первоначальных поисках. Вам нужно только подсчет только один раз. Кроме того, добавление строк не помогает делу.

Следующий код смог пропустить мой простой USB-накопитель в 300 мс и вернуть более 400 папок и 11000 файлов. На медленном сетевом диске он смог вернуть за 9 секунд 4000 файлов в 300 папках. Вероятно, его можно оптимизировать с помощью 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(); 
} 
Смежные вопросы