簡體   English   中英

LINQ搜索中的mscorlib.dll中發生了'System.OutOfMemoryException'類型的未處理異常

[英]An unhandled exception of type 'System.OutOfMemoryException' occurred in mscorlib.dll in LINQ Search

使用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;
}

}

您遇到的問題是基於嘗試同時加載多個GB的文本。 如果它們是文本文件,則可以流式傳輸它們,一次只比較一行。

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可以恢復內存。 如果要處理大文件/大量文件,將其重寫為流功能實際上會更好,然后,如果遇到搜索詞,並且您不需要一直在內存中存儲整個文件,則可以提早退出閱讀。

有關使用流在HTML文件中查找術語的上一個問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM