Чтение большого файла 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 ++, и я получил исключение "слишком большой файл для открытия".
Ответы
Ответ 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 ГБ, открытие файла и сохранение строки будет содержать данные дважды, есть накладные расходы на размер объекта....)
Вы не можете загрузить все это в память для обработки, вам нужно будет передать файл через вашу обработку.