C#directory.getfiles内存帮助

这是我正在使用的代码:

using (StreamWriter output = new StreamWriter(Path.Combine(masterdestination, "Master.txt"))) { string masterfolders = sourcefolder1; string[] filess = Directory.GetFiles(masterfolders, "*.txt"); foreach (string file in filess) { output.WriteLine(Path.GetFileName(file)); } } 

此代码将搜索用户指定目录中任何txt文件的所有文件。 这些目录有时包含2百万个文件。

在它运行的过程中监视这个过程我已经看到它爬升到800MB的内存使用量。 有没有办法可以保持这个过程的速度并限制它使用的内存? 或者让它读取并转储并继续? 哈希表? 任何想法都会很棒。

Directory.GetFiles真的很糟糕。 如果您可以使用.NET 4.0,则应该使用Directory.EnumerateFiles 。 来自文档:

EnumerateFiles和GetFiles方法的不同之处如下:使用EnumerateFiles时,可以在返回整个集合之前开始枚举名称集合; 当您使用GetFiles时,您必须等待返回整个数组的名称,然后才能访问该数组。 因此,当您使用许多文件和目录时,EnumerateFiles可以更高效。

如果您正在实施搜索,那么我建议您使用Windows Search 4.0

如果你不能使用Fx4,你最好自己编写FileEnumerator。 这是一个例子 。

Directory.GetFiles必须在返回之前构建所有匹配文件的列表。 只有这样你才能枚举它们。 当然,当有大量匹配文件时,它很昂贵。 它甚至可以在内部构建所有文件的列表。

如果您可以使用.NET 4.0,那么您可以使用Directory.EnumerateFiles ,它可以通过一次退回一个文件来避免此问题。 如果你不能,那么我建议你用C ++而不是C#来编写它。

在C ++中,您可以使用FindFirstFile ,它也会在一次返回文件。

 // iterate though the files in this directory // TCHAR szWild[MAX_PATH]; PathCombine(szWild, masterfolders, _T("*.txt")); WIN32_FIND_DATA fd; HANDLE hFind = FindFirstFile(szWild, &fd); if (INVALID_HANDLE_VALUE != hFind) { do { TCHAR szFileName[MAX_PATH]; PathCombine(szFileName, masterfolders, fd.cFileName); // write szFilename to output stream.. } while (FindNextFile(hFind, &fd)); FindClose (hFind); } 

正如在这里的答案中提到的,如果使用.NET 4.0,您可以使用Directory类上的静态EnumerateFiles方法来获取IEnumerable而不是string [],这会导致所有内存消耗。

如果您在.NET 4.0之前使用.NET版本,则可以通过P / Invoke层调用FindFirstFileEx,FindNextFile等方法轻松模仿此function。

然后,对于从对FindFirstFile / FindNextFile的调用返回的每个文件,您将返回该项。

这将减少因为EnumerateFiles对于具有大量文件的目录的内存消耗,因为您没有将它们全部加载到arrays中,而是在找到它们时让它们进行处理。