在 C# 中列出目录中的大量文件
Listing a very large number of files in a directory in C#
我正在尝试获取特定目录中的文件列表,其中包含超过 2000 万个文件,每个文件的大小从 2 到 20 KB 不等。
问题是我的程序每次都会抛出内存不足异常,而像 robocopy 这样的工具可以很好地将文件夹复制到另一个目录,完全没有问题。这是我用来枚举文件的代码:
List<string> files = new List<string>(Directory.EnumerateFiles(searchDir));
我应该怎么做才能解决这个问题?
任何帮助将不胜感激。
您正在内存中创建一个包含 2000 万个对象的列表。我认为你永远不会使用它,即使它成为可能。
而是使用 Directory.EnumerateFiles(searchDir)
并逐项迭代每个项目。
喜欢:
foreach(var file in Directory.EnumerateFiles(searchDir))
{
//Copy to other location, or other stuff
}
使用您当前的代码,您的程序将首先在内存中加载 2000 万个对象,然后您必须迭代或对它们执行操作。
参见:Directory.EnumerateFiles Method (String)
The EnumerateFiles and GetFiles methods differ as follows: When you
use EnumerateFiles, you can start enumerating the collection of
names before the whole collection is returned; when you use
GetFiles, you must wait for the whole array of names to be returned
before you can access the array. Therefore, when you are working with
many files and directories, EnumerateFiles can be more efficient.
上面的答案涵盖了一个目录级别。为了能够枚举多级目录,每个目录都有大量目录和大量文件,可以执行以下操作:
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));
}
}
}
该函数将通过枚举器遍历目录集合,因此它将逐一加载目录内容。剩下唯一要解决的就是层级的深度...
我正在尝试获取特定目录中的文件列表,其中包含超过 2000 万个文件,每个文件的大小从 2 到 20 KB 不等。
问题是我的程序每次都会抛出内存不足异常,而像 robocopy 这样的工具可以很好地将文件夹复制到另一个目录,完全没有问题。这是我用来枚举文件的代码:
List<string> files = new List<string>(Directory.EnumerateFiles(searchDir));
我应该怎么做才能解决这个问题? 任何帮助将不胜感激。
您正在内存中创建一个包含 2000 万个对象的列表。我认为你永远不会使用它,即使它成为可能。
而是使用 Directory.EnumerateFiles(searchDir)
并逐项迭代每个项目。
喜欢:
foreach(var file in Directory.EnumerateFiles(searchDir))
{
//Copy to other location, or other stuff
}
使用您当前的代码,您的程序将首先在内存中加载 2000 万个对象,然后您必须迭代或对它们执行操作。
参见:Directory.EnumerateFiles Method (String)
The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient.
上面的答案涵盖了一个目录级别。为了能够枚举多级目录,每个目录都有大量目录和大量文件,可以执行以下操作:
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));
}
}
}
该函数将通过枚举器遍历目录集合,因此它将逐一加载目录内容。剩下唯一要解决的就是层级的深度...