在C#中处理大文件时出现内存不足异常

Kau*_*hik 2 .net c# list visual-studio-2010 winforms

我有一个C#winforms应用程序,其中我使用OpenFileDialog让用户选择要打开的文本文件.(允许多个选择)一旦他们选择了文本文件,我逐个打开文件,获取文本并存储内容使用List.Add()操作的List变量.

当用户选择异常大量的文本文件(如1264个文本文件,总大小高达750MB)时,我的问题就出现了,程序无法处理它.它读取了大约850个文件然后给我一个内存不足的例外.在任务管理器中,当发生这种情况时,我的应用程序的内存(私有工作集)大约为1.5GB.我使用x64机器与32GB内存.

我给出了通读文件的代码:

public static List<LoadData> LoadDataFromFile(string[] filenames)
{
    List<LoadData> MasterData = new List<LoadData>();
    lookingForJobs = new LookingForJobs(1,filenames.Length);
    lookingForJobs.Show();
    /*-------OUTER LOOP TO GO THROUGH ALL THE FILES-------*/
    for (int index = 0; index < filenames.Length; index++)
    {
        string path = filenames[index];
        /*----------INNER LOOP TO GO THROUGH THE CONTENTS OF EACH FILE------*/
        foreach (string line in File.ReadAllLines(path))
        {
            string[] columns = line.Split('\t');
            if (columns.Length == 9)
            {
                if (line.StartsWith("<"))    /*-------IGNORING THE FIRST 8 LINES OF EACH LOG FILE CONTAINING THE LOGGER INFO---------*/
                {
                    MasterData.Add(new LoadData
                    {
                        Event_Type = columns[0],
                        Timestamp = columns[1],
                        Log_Message = columns[2],
                        Category = columns[3],
                        User = columns[4],
                        Thread_ID = columns[5],
                        Error_Code = columns[6],
                        Application = columns[7],
                        Machine = columns[8]
                    });
                }
            }
        }
        lookingForJobs.SearchingForJobsProgress.PerformStep();
        /*--------END OF INNER LOOP--------*/
    }
    lookingForJobs.Dispose();
    /*-----------END OF OUTER LOOP-----*/
    return MasterData;
}
Run Code Online (Sandbox Code Playgroud)

编辑:我知道我应该重新设计我的代码,以便不是所有文件都立即读入对象.但是,我想知道列表对象或内存(私有工作集)的大小是否有任何限制.我在一些文章中读到,当你达到1.5-1.6 GB时会出现这些问题.

Kon*_*osa 7

使用File.ReadLines而不是File.ReadAllLines第二个是不必要地将所有文件加载到内存中,而您一次只需要一行.MSDN说:

使用ReadAllLines时,必须等待返回整个字符串数组才能访问该数组.因此,当您使用非常大的文件时,ReadLines可以更高效.

这将为您提供相当大的内存改进.

第二个想法是重新考虑是否真的需要存储在内存中的如此大的数据.也许你可以只将文件路径存储到每个文件中并按需读取它们.