我正在尝试获取特定目录中的文件列表,其中包含超过2000万个文件,每个文件的范围为2到20 KB。 问题是我的程序每次抛出Out Of Memory Exception,而robocopy等工具在将文件夹复制到另一个目录时完全没有问题。这是我用来枚举文件的代码:
List<string> files = new List<string>(Directory.EnumerateFiles(searchDir));
我该怎么做才能解决这个问题? 任何帮助将不胜感激。
答案 0 :(得分:5)
您正在内存中创建一个包含2000万个对象的列表。即使有可能,我也不认为你会使用它。
而是使用Directory.EnumerateFiles(searchDir)
并逐个迭代每个项目。
像:
foreach(var file in Directory.EnumerateFiles(searchDir))
{
//Copy to other location, or other stuff
}
使用当前代码,您的程序将首先在内存中加载2000万个对象,然后您必须迭代或对它们执行操作。
请参阅:Directory.EnumerateFiles Method (String)
EnumerateFiles和GetFiles方法的区别如下:当你 使用 EnumerateFiles,您可以开始枚举集合 返回整个集合之前的名称; 时使用 GetFiles,您必须等待返回整个名称数组 在您可以访问阵列之前。因此,当你在工作 许多文件和目录,EnumerateFiles可以更有效。
答案 1 :(得分:1)
以上答案涵盖了一个目录级别。为了能够枚举多个级别的目录(每个目录都有大量的目录和大量的文件),可以执行以下操作:
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 fileEnumeratorFunc(directory)) {
yield return filePath;
}
directoryEnumerables.Enqueue(Directory.EnumerateDirectories(directory));
}
}
}
该函数将通过枚举器遍历目录的集合,因此它将一一加载目录内容。唯一要解决的是层次结构的深度...