如何加快在 C# 中获取目录内容的速度?
How can I speed up getting a directory's content in C#?
作为一个学习项目,我从事“文件资源管理器”项目已经有一段时间了,并且通过尝试新的编码方式获得一些乐趣。到目前为止,一切进展顺利,我对自己设法解决的问题感到非常满意。我遇到的障碍是速度。在 windows 资源管理器中,如果您进入一个新目录,它将(当然取决于版本和其他变量)只需要几分钟来列出所有文件和子目录。另一方面,我的应用程序仍然相当快,但目录中的项目越多,速度就会明显越慢。
我在“导航”功能中调用了这个功能。我相信这是我可能会找到罪魁祸首和解决方案的地方:
private void GetDirectoryContent(string directory)
{
txtPath.Text = directory;
currentDirectoryFiles.Clear();
filesList.Items.Clear();
int longestName = 0;
int longestType = 0;
foreach (string item in Directory.GetDirectories(directory))
{
int nameLength = item.Substring(item.LastIndexOf('\') + 1).Length;
if (nameLength > longestName) longestName = nameLength;
if ("Folder".Length > longestType) longestType = "Folder".Length;
}
foreach (string item in Directory.GetFiles(directory))
{
int nameLength = item.Substring(item.LastIndexOf('\') + 1).Length;
if (nameLength > longestName) longestName = nameLength;
if (GetFileType(item).Length > longestType) longestType = GetFileType(item).Length;
}
filesList.Sorting = SortOrder.Ascending;
filesList.View = View.Details;
filesList.Columns.Clear();
filesList.Columns.Add("Name", longestName * 8);
filesList.Columns.Add("Date Modified", 160);
filesList.Columns.Add("Type", longestType * 8);
foreach (string item in Directory.GetDirectories(directory))
{
string name = item.Substring(item.LastIndexOf('\') + 1);
smallImageList.Images.Add(new Bitmap(Environment.CurrentDirectory + "\Xplorer.ico"));
ListViewItem row = new ListViewItem(name, smallImageList.Images.Count - 1); // Name
row.SubItems.Add(Directory.GetLastWriteTime(item).ToString(CultureInfo.CurrentCulture)); // Date Modified
row.SubItems.Add("Folder"); // Type
row.Tag = "Folder";
currentDirectoryFiles.Add(item);
filesList.Items.Add(row);
}
foreach (string item in Directory.GetFiles(directory))
{
string name = item.Substring(item.LastIndexOf('\') + 1);
smallImageList.Images.Add(Icon.ExtractAssociatedIcon(item) ?? throw new InvalidOperationException());
ListViewItem row = new ListViewItem(name, smallImageList.Images.Count - 1); // Name
row.SubItems.Add(File.GetLastWriteTime(item).ToString(CultureInfo.CurrentCulture)); // Date Modified
row.SubItems.Add(GetFileType(item)); // Type
row.Tag = "File";
currentDirectoryFiles.Add(item);
filesList.Items.Add(row);
}
}
我仍然是一名新手程序员,所以我知道很多代码可能会被压缩,但我实际上不知道如何压缩,所以这就是我的主要问题。我怎样才能condense/optimize这个功能来加快结果(并且只是为了以后的项目遵循更好的做法。)
如果我遗漏了您可能需要的任何细节,请告诉我,正如我所说的,我还很新,不知道很多可能有用的信息。提前致谢!
似乎是学习项目的不错选择:)
也许使用 DirectoryInfo 而不是使用字符串进行搜索。这会让你更容易,而且可能会更快一点
private void GetDirectoryContent(DirectoryInfo directory)
{
//you could also leave it as string and write var dir = new DirectoryInfo(directory);
/*...*/
foreach (DirectoryInfo item in directory.GetDirectories())
{
string name = item.Name; //.FullName would include the path
smallImageList.Images.Add(new Bitmap(Environment.CurrentDirectory + "\Xplorer.ico"));
ListViewItem row = new ListViewItem(name, smallImageList.Images.Count - 1);
row.SubItems.Add(item.LastWriteTime.ToString(CultureInfo.CurrentCulture))
row.SubItems.Add("Folder"); // Type
row.Tag = "Folder";
currentDirectoryFiles.Add(item);
filesList.Items.Add(row);
}
foreach (FileInfo item in directory.GetFiles())
{
/* also knows its name, extension, last write time, ...*/
}
/*...*/
}
如果你走得远一点并且感觉舒服,也许还可以尝试一些新东西。我认为对您的学习项目有用的东西是 IEnumerables 或递归(它对像文件系统这样的树状结构非常有用)
感谢大家的帮助!这是一个新功能,运行速度非常快!
private void GetDirectoryContent(string directory)
{
txtPath.Text = directory;
currentDirectoryFiles.Clear();
filesList.Items.Clear();
string[] files = Directory.EnumerateFiles(directory).ToArray();
string[] directories = Directory.EnumerateDirectories(directory).ToArray();
filesList.Sorting = SortOrder.Ascending;
filesList.View = View.Details;
filesList.Columns.Clear();
filesList.Columns.Add("Name", 250);
filesList.Columns.Add("Date Modified", 160);
filesList.Columns.Add("Type", 125);
foreach (string item in directories)
{
string name = item.Substring(item.LastIndexOf('\') + 1);
smallImageList.Images.Add(new Bitmap(Environment.CurrentDirectory + "\Xplorer.ico"));
ListViewItem row = new ListViewItem(name, smallImageList.Images.Count - 1); // Name
row.SubItems.Add(Directory.GetLastWriteTime(item).ToString(CultureInfo.CurrentCulture)); // Date Modified
row.SubItems.Add("Folder"); // Type
row.Tag = "Folder";
currentDirectoryFiles.Add(item);
filesList.Items.Add(row);
}
foreach (string item in files)
{
string name = item.Substring(item.LastIndexOf('\') + 1);
smallImageList.Images.Add(Icon.ExtractAssociatedIcon(item) ?? throw new InvalidOperationException());
ListViewItem row = new ListViewItem(name, smallImageList.Images.Count - 1); // Name
row.SubItems.Add(File.GetLastWriteTime(item).ToString(CultureInfo.CurrentCulture)); // Date Modified
row.SubItems.Add(GetFileType(item)); // Type
row.Tag = "File";
currentDirectoryFiles.Add(item);
filesList.Items.Add(row);
}
}
作为一个学习项目,我从事“文件资源管理器”项目已经有一段时间了,并且通过尝试新的编码方式获得一些乐趣。到目前为止,一切进展顺利,我对自己设法解决的问题感到非常满意。我遇到的障碍是速度。在 windows 资源管理器中,如果您进入一个新目录,它将(当然取决于版本和其他变量)只需要几分钟来列出所有文件和子目录。另一方面,我的应用程序仍然相当快,但目录中的项目越多,速度就会明显越慢。
我在“导航”功能中调用了这个功能。我相信这是我可能会找到罪魁祸首和解决方案的地方:
private void GetDirectoryContent(string directory)
{
txtPath.Text = directory;
currentDirectoryFiles.Clear();
filesList.Items.Clear();
int longestName = 0;
int longestType = 0;
foreach (string item in Directory.GetDirectories(directory))
{
int nameLength = item.Substring(item.LastIndexOf('\') + 1).Length;
if (nameLength > longestName) longestName = nameLength;
if ("Folder".Length > longestType) longestType = "Folder".Length;
}
foreach (string item in Directory.GetFiles(directory))
{
int nameLength = item.Substring(item.LastIndexOf('\') + 1).Length;
if (nameLength > longestName) longestName = nameLength;
if (GetFileType(item).Length > longestType) longestType = GetFileType(item).Length;
}
filesList.Sorting = SortOrder.Ascending;
filesList.View = View.Details;
filesList.Columns.Clear();
filesList.Columns.Add("Name", longestName * 8);
filesList.Columns.Add("Date Modified", 160);
filesList.Columns.Add("Type", longestType * 8);
foreach (string item in Directory.GetDirectories(directory))
{
string name = item.Substring(item.LastIndexOf('\') + 1);
smallImageList.Images.Add(new Bitmap(Environment.CurrentDirectory + "\Xplorer.ico"));
ListViewItem row = new ListViewItem(name, smallImageList.Images.Count - 1); // Name
row.SubItems.Add(Directory.GetLastWriteTime(item).ToString(CultureInfo.CurrentCulture)); // Date Modified
row.SubItems.Add("Folder"); // Type
row.Tag = "Folder";
currentDirectoryFiles.Add(item);
filesList.Items.Add(row);
}
foreach (string item in Directory.GetFiles(directory))
{
string name = item.Substring(item.LastIndexOf('\') + 1);
smallImageList.Images.Add(Icon.ExtractAssociatedIcon(item) ?? throw new InvalidOperationException());
ListViewItem row = new ListViewItem(name, smallImageList.Images.Count - 1); // Name
row.SubItems.Add(File.GetLastWriteTime(item).ToString(CultureInfo.CurrentCulture)); // Date Modified
row.SubItems.Add(GetFileType(item)); // Type
row.Tag = "File";
currentDirectoryFiles.Add(item);
filesList.Items.Add(row);
}
}
我仍然是一名新手程序员,所以我知道很多代码可能会被压缩,但我实际上不知道如何压缩,所以这就是我的主要问题。我怎样才能condense/optimize这个功能来加快结果(并且只是为了以后的项目遵循更好的做法。)
如果我遗漏了您可能需要的任何细节,请告诉我,正如我所说的,我还很新,不知道很多可能有用的信息。提前致谢!
似乎是学习项目的不错选择:) 也许使用 DirectoryInfo 而不是使用字符串进行搜索。这会让你更容易,而且可能会更快一点
private void GetDirectoryContent(DirectoryInfo directory)
{
//you could also leave it as string and write var dir = new DirectoryInfo(directory);
/*...*/
foreach (DirectoryInfo item in directory.GetDirectories())
{
string name = item.Name; //.FullName would include the path
smallImageList.Images.Add(new Bitmap(Environment.CurrentDirectory + "\Xplorer.ico"));
ListViewItem row = new ListViewItem(name, smallImageList.Images.Count - 1);
row.SubItems.Add(item.LastWriteTime.ToString(CultureInfo.CurrentCulture))
row.SubItems.Add("Folder"); // Type
row.Tag = "Folder";
currentDirectoryFiles.Add(item);
filesList.Items.Add(row);
}
foreach (FileInfo item in directory.GetFiles())
{
/* also knows its name, extension, last write time, ...*/
}
/*...*/
}
如果你走得远一点并且感觉舒服,也许还可以尝试一些新东西。我认为对您的学习项目有用的东西是 IEnumerables 或递归(它对像文件系统这样的树状结构非常有用)
感谢大家的帮助!这是一个新功能,运行速度非常快!
private void GetDirectoryContent(string directory)
{
txtPath.Text = directory;
currentDirectoryFiles.Clear();
filesList.Items.Clear();
string[] files = Directory.EnumerateFiles(directory).ToArray();
string[] directories = Directory.EnumerateDirectories(directory).ToArray();
filesList.Sorting = SortOrder.Ascending;
filesList.View = View.Details;
filesList.Columns.Clear();
filesList.Columns.Add("Name", 250);
filesList.Columns.Add("Date Modified", 160);
filesList.Columns.Add("Type", 125);
foreach (string item in directories)
{
string name = item.Substring(item.LastIndexOf('\') + 1);
smallImageList.Images.Add(new Bitmap(Environment.CurrentDirectory + "\Xplorer.ico"));
ListViewItem row = new ListViewItem(name, smallImageList.Images.Count - 1); // Name
row.SubItems.Add(Directory.GetLastWriteTime(item).ToString(CultureInfo.CurrentCulture)); // Date Modified
row.SubItems.Add("Folder"); // Type
row.Tag = "Folder";
currentDirectoryFiles.Add(item);
filesList.Items.Add(row);
}
foreach (string item in files)
{
string name = item.Substring(item.LastIndexOf('\') + 1);
smallImageList.Images.Add(Icon.ExtractAssociatedIcon(item) ?? throw new InvalidOperationException());
ListViewItem row = new ListViewItem(name, smallImageList.Images.Count - 1); // Name
row.SubItems.Add(File.GetLastWriteTime(item).ToString(CultureInfo.CurrentCulture)); // Date Modified
row.SubItems.Add(GetFileType(item)); // Type
row.Tag = "File";
currentDirectoryFiles.Add(item);
filesList.Items.Add(row);
}
}