在c#中列出目录中非常多的文件

本文关键字:非常 文件 | 更新日期: 2023-09-27 18:09:23

我正在尝试获取特定目录中的文件列表,该目录包含超过2000万个文件,每个文件从2到20 KB不等。
问题是我的程序每次都会抛出内存不足异常,而像robocopy这样的工具可以很好地将文件夹复制到另一个目录,完全没有问题。下面是我用来枚举文件的代码:

            List<string> files = new List<string>(Directory.EnumerateFiles(searchDir));

我该怎么做才能解决这个问题?

在c#中列出目录中非常多的文件

您正在内存中创建一个包含2000万个对象的列表。我不认为你会用到它,即使它成为可能。

改为使用to Directory.EnumerateFiles(searchDir)并逐个迭代每个项。

:

foreach(var file in Directory.EnumerateFiles(searchDir))
{
   //Copy to other location, or other stuff
}

在你当前的代码中,你的程序首先将有2000万个对象加载到内存中,然后你必须对它们进行迭代或执行操作。

看:目录。EnumerateFiles Method (String)

EnumerateFiles和GetFiles方法的区别如下使用EnumerateFiles,您可以开始枚举GetFiles,则必须等待返回整个名称数组才能访问数组。因此,当你与对于许多文件和目录,EnumerateFiles可以更高效。

上面的答案涵盖了一个目录级别。为了能够枚举多个级别的目录,每个目录都有大量的目录和大量的文件,可以执行以下操作:

public IEnumerable<string> EnumerateFiles(string startingDirectoryPath) {
    var directoryEnumerables = new Queue<IEnumerable<string>>();
    directoryEnumerables.Enqueue(new string[] { startingDirectoryPath });
    while (directoryEnumerables.Any()) {
        var currentDirectoryEnumerable = directoryEnumerables.Dequeue();
        foreach (var directory in currentDirectoryEnumerable) {
            foreach (var filePath in EnumerateFiles(directory)) {
                yield return filePath;
            }
            directoryEnumerables.Enqueue(Directory.EnumerateDirectories(directory));
        }                
    }
}

函数将通过枚举器遍历目录集合,因此它将逐个加载目录内容。唯一需要解决的问题是层次结构的深度…