C# LINQ搜索中的mscorlib.dll中发生类型为“System.OutOfMemoryException”的未处理异常
使用MSDN中的文章,我试图搜索目录中的文件。问题是,每次执行程序时,我都会得到: mscorlib.dll中发生类型为“System.OutOfMemoryException”的未处理异常 我尝试了一些其他选项,如StreamReader,但我无法让它工作。这些文件很大。其中一些文件的大小在1.5-2GB之间,每天可能有5个或更多文件 此代码失败:C# LINQ搜索中的mscorlib.dll中发生类型为“System.OutOfMemoryException”的未处理异常,c#,linq,C#,Linq,使用MSDN中的文章,我试图搜索目录中的文件。问题是,每次执行程序时,我都会得到: mscorlib.dll中发生类型为“System.OutOfMemoryException”的未处理异常 我尝试了一些其他选项,如StreamReader,但我无法让它工作。这些文件很大。其中一些文件的大小在1.5-2GB之间,每天可能有5个或更多文件 此代码失败: private static string GetFileText(string name) { var fileContents = s
private static string GetFileText(string name)
{
var fileContents = string.Empty;
// If the file has been deleted since we took
// the snapshot, ignore it and return the empty string.
if (File.Exists(name))
{
fileContents = File.ReadAllText(name);
}
return fileContents;
}
你知道会发生什么,或者如何让它在没有记忆错误的情况下阅读吗
完整的代码,以防您不想打开MSDN文章
class QueryContents {
public static void Main()
{
// Modify this path as necessary.
string startFolder = @"c:\program files\Microsoft Visual Studio 9.0\";
// Take a snapshot of the file system.
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
// This method assumes that the application has discovery permissions
// for all folders under the specified path.
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories);
string searchTerm = @"Visual Studio";
// Search the contents of each file.
// A regular expression created with the RegEx class
// could be used instead of the Contains method.
// queryMatchingFiles is an IEnumerable<string>.
var queryMatchingFiles =
from file in fileList
where file.Extension == ".htm"
let fileText = GetFileText(file.FullName)
where fileText.Contains(searchTerm)
select file.FullName;
// Execute the query.
Console.WriteLine("The term \"{0}\" was found in:", searchTerm);
foreach (string filename in queryMatchingFiles)
{
Console.WriteLine(filename);
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
// Read the contents of the file.
static string GetFileText(string name)
{
string fileContents = String.Empty;
// If the file has been deleted since we took
// the snapshot, ignore it and return the empty string.
if (System.IO.File.Exists(name))
{
fileContents = System.IO.File.ReadAllText(name);
}
return fileContents;
}
}您遇到的问题是试图同时加载多个千兆字节的文本。如果它们是文本文件,您可以对它们进行流式处理,一次只比较一行
var queryMatchingFiles =
from file in fileList
where file.Extension == ".htm"
let fileLines = File.ReadLines(file.FullName) // lazy IEnumerable<string>
where fileLines.Any(line => line.Contains(searchTerm))
select file.FullName;
我建议您出现内存不足错误,因为按照编写查询的方式,我相信您需要将每个文件的整个文本加载到内存中,并且在加载整个文件集之前,无法释放任何对象。您能不能在GetFileText函数中检查搜索词,然后只返回true或false 如果您这样做了,那么文件文本至少会在函数末尾超出范围,并且GC可以恢复内存。事实上,如果你处理的是大文件/数量的文件,最好将其重写为流式功能。如果你遇到搜索词,你可以提前退出阅读,而不需要一直将整个文件保存在内存中
正是我需要的。。非常感谢你!只要确保你的搜索词不包含换行符;以前linq查询迭代中使用的对象符合GC条件。但流方法当然是合理的。