我使用下面的代码从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 :(得分:0)
答案 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();
}