Как я могу прочитать очень большой текстовый файл с помощью StreamReader?

Я хочу прочитать огромный файл .txt, и у меня возникает переполнение памяти из-за его огромного размера.

Любая помощь?

    private void button1_Click(object sender, EventArgs e)
    {
        using (var Reader = new StreamReader(@"C:\Test.txt"))
        {
            textBox1.Text += Reader.ReadLine();
        }
    }

Текстовый файл просто:

Line1
Line2
Line3

Буквально так.

Я хочу загрузить текстовый файл в многострочное текстовое поле как есть, 100% копия.


person Community    schedule 19.05.2010    source источник
comment
Прочитайте и обработайте его по одной строке за раз или разбейте его на куски и работайте с ними по отдельности. Вы также можете показать нам код, который у вас есть, и рассказать, что вы пытаетесь с его помощью выполнить.   -  person Robert Harvey    schedule 19.05.2010
comment
Как бы я это сделал? Я видел аналогичный вопрос здесь, в SO, но не могу его найти. Поиск у меня плохо работает.   -  person    schedule 19.05.2010
comment
@Robert Если вы опубликуете это, вы получите положительный отзыв :)   -  person Simon    schedule 19.05.2010
comment
Совет по поиску @Sergio: попробуйте ключевое слово1 + ключевое слово2 и т. д. :)   -  person rlb.usa    schedule 19.05.2010
comment
Как у вас происходит переполнение памяти, когда вы читаете только одну строку текста?   -  person Ben M    schedule 19.05.2010
comment
Каков размер текстового файла? Существует практическое ограничение свойства textBox1.Text.   -  person code4life    schedule 19.05.2010


Ответы (4)


Во-первых, код, который вы разместили, поместит только первую строку файла в TextBox. Что вы хотите, так это:

using (var reader = new StreamReader(@"C:\Test.txt"))
{
    while (!reader.EndOfStream)
        textBox1.Text += reader.ReadLine();
}

Теперь что касается OutOfMemoryException: я не проверял это, но пробовали ли вы метод TextBox.AppendText вместо использования +=? Последний, безусловно, будет выделять массу строк, большинство из которых будут иметь длину почти всего файла к тому времени, когда вы приблизитесь к концу файла.

Насколько я знаю, AppendText тоже так делает; но его существование заставляет меня подозревать, что оно создано для того, чтобы иметь дело с этим сценарием. Я могу ошибаться - как я уже сказал, лично не проверял.

person Dan Tao    schedule 19.05.2010
comment
Итак, читателю нужен вызов EndOfStream, чтобы использовать предыдущую строку, чтобы можно было прочитать следующую строку? Я этого не знал. Кажется немного нелогичным. - person Robert Harvey; 19.05.2010
comment
@Robert Harvey: Нет, не нужно вызывать EndOfStream, чтобы использовать предыдущую строку; ему просто нужно проверить это свойство, чтобы знать, когда остановиться. Проблема заключалась в том, что ОП вообще не использовал цикл; он постоянно создавал новый StreamReader и вызывал ReadLine один раз для каждого экземпляра. - person Dan Tao; 19.05.2010
comment
+= в текстовом разделе текстового поля — это просто += в строке. Это худший способ добавить текст к строке в .net. По мере увеличения размера текста использование памяти становится все хуже и хуже. - person Justin; 19.05.2010
comment
@Justin: я понимаю это; вот почему я предложил вместо этого попробовать AppendText. Но я должен был быть честным и признать, что я не совсем уверен, что AppendText не просто звонит самому себе +=. - person Dan Tao; 19.05.2010
comment
Протестировано с файлом размером 7 ГБ на машине x64. работал хорошо, - person Rajat; 31.03.2017

Вы получите гораздо более высокую производительность со следующим:

textBox1.Text = File.ReadAllText(@"C:\Test.txt");

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

Конечно, сборщик мусора должен собрать старые строки, прежде чем вы увидите OutOfMemoryException, но я бы все равно попробовал вышеописанное.

person Ben M    schedule 19.05.2010

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

// use a string builer, the += on that many strings increasing in size
// is causing massive memory hoggage and very well could be part of your problem
StringBuilder sb = new StringBuilder();

// open a stream reader
using (var reader = new StreamReader(@"C:\Test.txt"))
{
    // read through the stream loading up the string builder
    while (!reader.EndOfStream)
    {
       sb.Append( reader.ReadLine() );
    }
}

// set the text and null the string builder for GC
textBox1.Text = sb.ToString();
sb = null;
person Justin    schedule 19.05.2010

Прочитайте и обработайте его по одной строке за раз или разбейте его на куски и работайте с ними по отдельности. Вы также можете показать нам код, который у вас есть, и рассказать, что вы пытаетесь с его помощью выполнить.

Вот пример: Чтение текстового файла C#, содержащего данные, разделенные табуляцией Обратите внимание на операторы ReadLine() и WriteLine().

TextBox сильно ограничен количеством символов, которые он может содержать. Вы можете попробовать использовать метод AppendText() для RichTextBox вместо этого.

person Robert Harvey    schedule 19.05.2010
comment
Роберт, он правильно читает первую строку Line1, но не захватывает Line2 или Line3. Я пытаюсь создать буквальную копию текстового файла, форматирование и все такое. - person ; 19.05.2010
comment
@Sergio: Попробуйте RichTextBox. Если файл не очень большой, он должен работать; RichTextBox гораздо лучше подходит для такого рода вещей. - person Robert Harvey; 19.05.2010
comment
Метод ReadLine() снова и снова возвращает мою первую строку; как я могу сказать ему прочитать первую строку, а затем продолжить движение? - person ; 19.05.2010
comment
@Sergio: вам нужно сделать это в цикле while, проверяя свойство EndOfStream на каждой итерации. Взгляните на мой ответ. - person Dan Tao; 19.05.2010