c# -如何以优化的方式快速列出子目录中的文件

本文关键字:子目录 文件 方式快 优化 | 更新日期: 2023-09-27 18:10:13

我试图用以下方法列出根目录的所有子目录中的文件。但是当文件的数量达到数百万时,需要花费很多时间。有没有更好的方法来做这件事呢?

我使用的是。net 3.5,所以不能使用enumerator:-(

)
        ******************* Main *************
        DirectoryInfo dir = new DirectoryInfo(path);
        DirectoryInfo[] subDir = dir.GetDirectories();
        foreach (DirectoryInfo di in subDir) //call for each sub directory
        {
             PopulateList(di.FullName, false);
        }
        *******************************************
        static void PopulateList(string directory, bool IsRoot)
        {
            System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + "dir /s/b '"" + directory + "'"");
            procStartInfo.RedirectStandardOutput = true;
            procStartInfo.UseShellExecute = false;
            procStartInfo.CreateNoWindow = true;
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.StartInfo = procStartInfo;
            proc.Start();
            string fileName = directory.Substring(directory.LastIndexOf('''') + 1);
            StreamWriter writer = new StreamWriter(fileName + ".lst");
            while (proc.StandardOutput.EndOfStream != true)
            {
                 writer.WriteLine(proc.StandardOutput.ReadLine());
                 writer.Flush();
            }
            writer.Close();
        }

c# -如何以优化的方式快速列出子目录中的文件

删除所有与process相关的东西并尝试Directory。GetDirectories()和Directory.GetFiles()方法:

public IEnumerable<string> GetAllFiles(string rootDirectory)
{
    foreach(var directory in Directory.GetDirectories(
                                            rootDirectory, 
                                            "*", 
                                            SearchOption.AllDirectories))
    {
        foreach(var file in Directory.GetFiles(directory))
        {
            yield return file;
        }
    }
}

来自MSDN, SearchOption。AllDirectories:

包含当前目录和搜索中的所有子目录操作。该选项包括重新解析点,如挂载的驱动器和搜索中的符号链接。

在每个目录的循环中使用DirectoryInfo.GetFiles肯定会更快,而不是产生大量的新进程来读取它们的输出。

对于数以百万计的文件,您实际上会遇到文件系统限制(参见此并搜索"300,000"),因此请考虑到这一点。

至于优化,我认为你真的想要延迟迭代,所以你必须p/Invoke到FindFirstFile/FindNextFile

查看已经可用的目录。getfile过载。
例如:

var paths = Directory.GetFiles(root, "*", SearchOption.AllDirectories);

是的,这将花费很多时间。但是我不认为你可以仅仅使用。net类来提高它的性能。

假设您的数百万个文件分布在多个子目录中,并且您使用的是。net 4.0,您可以查看并行扩展。

使用并行foreach循环来处理子目录列表,可以使事情更快。

新的并行扩展也比在底层尝试多线程更安全,更容易使用。

要注意的一件事是确保将并发进程的数量限制在合理的范围内。