Чтение большого файла TXT, исключение нехватки памяти

Я хочу прочитать большой размер файла TXT составляет 500 МБ, сначала я использую

var file = new StreamReader(_filePath).ReadToEnd();  
var lines = file.Split(new[] { '\n' });

но он выбрасывает из памяти Exception, затем я пытался читать построчно, но снова после чтения около 1,5 миллионов строк он выбрасывает из памяти Exception

  using (StreamReader r = new StreamReader(_filePath))
         {            
             while ((line = r.ReadLine()) != null)            
                 _lines.Add(line);            
         }

или я использовал

  foreach (var l in File.ReadLines(_filePath))
            {
                _lines.Add(l);
            }

но опять я получил

Исключение типа 'System.OutOfMemoryException» произошла в mscorlib.dll, но не была обработана в коде пользователя

Моя машина - мощная машина с 8 ГБ памяти, поэтому она не должнаЭто не моя машинная проблема.

PS: я пытался открыть этот файл в NotePadd ++, и я получил 'файл слишком велик для открытия исключение.

 CyberDude16 нояб. 2012 г., 12:46
Какой смысл хранить все это в коллекции?
 Behnam16 нояб. 2012 г., 12:53
@JonSkeet извините размер файла составляет 500 МБ
 Behnam16 нояб. 2012 г., 12:47
@ AlvinWong проблема в том, почему я получил исключение из памяти, и как я могу это решить
 CyberDude16 нояб. 2012 г., 12:58
Вы можете это исправить,не загрузка всего файла в память. Очевидно, что ваш дизайн не подходит для нужд приложения. Что вы будете в конечном итоге делать с этими данными? Любая обработка, фильтрация и т. Д.? Может быть, вам нужно сначала сохранить его в базе данных.
 Behnam16 нояб. 2012 г., 12:48
@ CyberDude, то я использовал список в другой части приложения
 Alvin Wong16 нояб. 2012 г., 12:46
В чем вопрос? Вы'только описываю вещи.
 Hans Kesting16 нояб. 2012 г., 12:56
@Behnam - 500 ГБ файла в 8 ГБ памяти? Это не будет соответствовать. Вам нужно будет найти какой-то другой способ обработки файла, который не требует всего этого в памяти. Процесс на строку (или, возможно, на небольшое количество строк)
 Jon Skeet16 нояб. 2012 г., 12:48
Вы говорите о500 рядов " но насколько большой файл с точки зрениябайтов а такжеперсонажи? 500 строк по 80 символов не должныЭто не проблема - 500 строк из миллиарда символов в каждой строке.
 Behnam16 нояб. 2012 г., 13:01
@CyberData, даже если я удалю _lines.Add (line); и просто читая файл, он создает OutOfMemoryException, так чтоВаше предложение просто прочитать файл.

Ответы на вопрос(4)

загрузка всего файла в память приведет к росту объектов, и .net вызовет исключения OOM, если не сможет выделить достаточно непрерывной памяти для объекта.

Ответ все тот же, вам нужно потоковое воспроизведение файла, а не читать все содержимое. Это может потребовать перестройки архитектуры вашего приложения, однако с использованиемIEnumerable<> методы, которые вы можете объединить в бизнес-процессы в разных областях приложения и отложить обработку.

мощный» машина с 8 ГБ оперативной памяти нене будет возможности сохранить файл 500 ГБ в памяти, так как 500 больше, чем 8. (плюс вы неполучить 8, поскольку операционная система будет держать некоторые, вы можете• Выделите всю память в .Net, 32-битный имеет ограничение в 2 ГБ, открытие файла и сохранение строки будет содержать данные дважды, есть накладные расходы на размер объекта ....)

Вы можете'Чтобы загрузить все это в память для обработки, вам придется передавать файл в процессе обработки.

 cjk16 нояб. 2012 г., 14:45
@igrimpe Хороший вызов на этом
 igrimpe16 нояб. 2012 г., 13:48
Может быть, "линия" терминатор не то, что должно быть? Если строки не заканчиваются на \ r AND \ n, внутренние функции, вероятно, все равно будут считывать весь файл в память, нене так ли?
 Behnam16 нояб. 2012 г., 12:57
большое спасибо за ваш ответ, но этос 500 МБ, а не 500 ГБ
 igrimpe16 нояб. 2012 г., 14:02
Тестирование, если проблема с ограничителем строки, должно быть простым. Сделать консольное приложение одним методомfile.readline(path), Если он все еще выбрасывает бывшего, то сингллиния" просто слишком долго Скорее всего, потому что внутри используется строитель строк, который постоянно должен увеличивать свой внутренний массив (то есть выделять место для нового), не давая GC время на очистку.
 Behnam16 нояб. 2012 г., 13:22
Во втором подходе я попытался использовать StreamReader и даже с удалением _lines.Add (line); линия, я получаю OutOfMemoryException. так что я неЯ не понимаю, что вы подразумеваете под потоковым
 cjk16 нояб. 2012 г., 13:54
я не уверен, почему вы получили ошибку в своем втором фрагменте кода, когда не звонил_lines.Add(line), может быть, у вас есть проблема в другом месте? Терминатор строки, вероятно, не связан с проблемой - 500 МБ непрерывной памяти будет трудно получить в любом сценарии, если вы не используете 64-разрядную версию и не имеете много памяти.

но вы можете прочитать до 2 147 483 647 строк.

int intNoOfLines = 0;
using (StreamReader oReader = new 
StreamReader(MyFilePath))
{
    while (oReader.ReadLine() != null) intNoOfLines++;
}
string[] strArrLines = new string[intNoOfLines];
int intIndex = 0;
using (StreamReader oReader = new 
StreamReader(MyFilePath))
{
    string strLine;
    while ((strLine = oReader.ReadLine()) != null)
    {
       strArrLines[intIndex++] = strLine;
    }
}
Решение Вопроса

Просто используйтеFile.ReadLines который возвращаетIEnumerable и незагрузить все строки одновременно в память.

foreach (var line in File.ReadLines(_filePath))
{
    //Don't put "line" into a list or collection.
    //Just make your processing on it.
}
 L.B16 нояб. 2012 г., 14:05
@Behnam Я только что протестировал его с текстовым файлом 8,7 ГБ (120 000 000 строк) и работал хорошо.
 Behnam16 нояб. 2012 г., 13:36
Та же проблема, даже если просто использовать пустой цикл foreach (строка var в File.ReadLines (_filePath)) {}
 Behnam16 нояб. 2012 г., 13:53
Я только что создал консольное приложение, которое просто строка кода foreach (var line в File.ReadLines (_filePath)) {}, но оно снова создает исключение.
 L.B16 нояб. 2012 г., 13:42
@Behnam Вы уверены, что не получаете эту ошибку от других частей вашей программы. Попробуйте это в пустом решении.

причиной исключения является растущая коллекция _lines, но не чтение большого файла. Вы читаете строку иadding to some collection _lines which will be taking memory and causing out of memory execption, Вы можете применить фильтры, чтобы поместить только необходимые строки в коллекцию _lines.

 Behnam16 нояб. 2012 г., 12:54
OutOfMemoryException
 Adil16 нояб. 2012 г., 12:52
Какое исключение он бросает сейчас?
 Behnam16 нояб. 2012 г., 12:51
Я просто удаляю строку, которая добавляет данные в коллекцию _lines, но проблема все еще существует.

Ваш ответ на вопрос