C# LINQ搜索中的mscorlib.dll中发生类型为“System.OutOfMemoryException”的未处理异常

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

使用MSDN中的文章,我试图搜索目录中的文件。问题是,每次执行程序时,我都会得到:

mscorlib.dll中发生类型为“System.OutOfMemoryException”的未处理异常

我尝试了一些其他选项,如StreamReader,但我无法让它工作。这些文件很大。其中一些文件的大小在1.5-2GB之间,每天可能有5个或更多文件

此代码失败:

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条件。但流方法当然是合理的。