如何加快在 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);
    }
}