Подтвердить что ты не робот

Чтение большого файла 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, но не был обработан в коде пользователя

My Machine - мощная машина с 8 ГБ оперативной памяти, поэтому это не должно быть проблемой для моего компьютера.

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

4b9b3361

Ответ 1

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

foreach (var line in File.ReadLines(_filePath))
{
    //Don't put "line" into a list or collection.
    //Just make your processing on it.
}

Ответ 2

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

Ответ 3

Edit:

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

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


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

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