2015-11-24 8 views
0

Я немного новичок в C#, и у меня возникают проблемы с производительностью. В моей программе люди импортируют список .txt, и программа делает список из него; проблема в том, что он потребляет слишком много ОЗУ, сбой ПК с низкой памятью. Я думал об использовании «урожая» без успеха. Есть идеи?Список оптимизации <string>

private List<string> ImportList() 
{ 
    try 
    { 
     using (var ofd = new OpenFileDialog() { Filter = "Text files (*.txt) | *.txt" }) 
     { 
      if (ofd.ShowDialog() == DialogResult.OK) 
      { 
       return File.ReadAllLines(ofd.FileName).ToList(); 
      } 
     } 

     return null; 
    } 
    catch(OutOfMemoryException ex) 
    { 
     MessageBox.Show("The list is too large. Try using a smaller list or dividing it.", "Warning!"); 
     return null; 

    } 
} 
+1

Насколько велики этих файлов? – zerkms

+0

До 550mb. Они могут быть больше –

+0

И что происходит с возвращенным 'List ' next? – zerkms

ответ

5

метод ReadlAllLines возвращает массив строки, а не List =>File.ReadAllLines Method (String)

Я думаю, что вы shuld использовать ReadLines(), проверить это Question о diferences между ReadLines и ReadlAllLines:

есть ли разница в производительности, связанная с этими методами? ДА есть разница

File.ReadAllLines() метод читает весь файл в то время, и возвращает строку [] массив, так что это занимает много времени, работая с большим размером файлов и не рекомендуются, поскольку пользователь имеет ждать до полного массива .

Файл.ReadLines() возвращает IEnumerable и не читает весь файл за один раз, поэтому это действительно лучший вариант при работе с файлами большого размера.

От MSDN:

В ReadLines и методы ReadAllLines отличаются следующим образом:

При использовании ReadLines, вы можете начать перечисление коллекции строки до вся коллекция возвращается; когда вы используете ReadAllLines, вы должны дождаться возврата всего массива строк , прежде чем вы сможете получить доступ к массиву. Поэтому, когда вы работаете с очень большими файлами, ReadLines может быть более эффективным. Пример 1: File.ReadAllLines()

string[] lines = File.ReadAllLines("C:\\mytxt.txt"); 

Пример 2: Файл.ReadLines()

foreach (var line in File.ReadLines("C:\\mytxt.txt")) 
{ 

    //Do something  

} 

Ответ на Sudhakar Tillapudi

+3

Возможно, должен был быть отмечен вопрос как _duplicate_, а не цитирования другого ответа – MickyD

+0

Возможно, Микки, но вопрос был «Оптимизирующий список », а не различие между ReadALlLines и ReadLines – Bradley

0

Read Big TXT File, Out of Memory Exception

Я просто скопировал наклеить решение от другого вопроса. Посмотрите, работает ли это.

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

ReadLines возвращается IEnumerable<string>. File.ReadLine

Концепция состоит в том, чтобы не загружать сразу все строки в список. Даже если вы хотите их обрабатывать, обрабатывайте их по строкам, используя IEnumerable вместо List.

0

Если исключение происходит в ReadAllLines, попробуйте следующее:

Использовать StreamReader прочитать файл построчно и объявлением, чтобы это список. Что-то вроде этого:

using (StreamReader sr = new StreamReader (ofd.FileName)) { 
    while (!sr.EndOfStream) { 
     yourList.Add (sr.ReadLine()); 
    } 
} 

Если исключение происходит в ToList, попробуйте следующее:

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

foreach (var str in arrayReturned) { 
    yourList.Add (str); 
} 

Если это все еще не работает, используйте метод ReadLines в том же классе. Разница между ReaDAllLines и ReadLines заключается в том, что последний возвращает IEnumerable<string> вместо string[]. IEnumerable<string> использование отсроченное исполнение. Это даст вам только один элемент, когда вы его попросите. Книга Джона Скита, C# In Depth рассказывает об этом подробно.

Вот Документы для ReadLines для получения дополнительной информации:

https://msdn.microsoft.com/en-us/library/dd383503(v=vs.110).aspx

Смежные вопросы