0

I am a little new to C# and I'm having performance issues with this. In my program, people import a .txt list and the program makes a list out of it; the problem is its consuming too much RAM, crashing PC's with low memory. I thought of using 'yield' without success. Any ideas?

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;

    }
}
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321

3 Answers3

5

the method ReadlAllLines returns an array of string, not a List => File.ReadAllLines Method (String)

I think that you shuld use ReadLines(), check this Question about the diferences between ReadLines and ReadlAllLines:

is there any performance difference related to these methods? YES there is a difference

File.ReadAllLines() method reads the whole file at a time and returns the string[] array, so it takes time while working with large size of files and not recommended as user has to wait untill the whole array is returned.

File.ReadLines() returns an IEnumerable and it does not read the whole file at one go, so it is really a better option when working with large size files.

From MSDN:

The ReadLines and ReadAllLines methods differ as follows:

When you use ReadLines, you can start enumerating the collection of strings before the whole collection is returned; when you use ReadAllLines, you must wait for the whole array of strings be returned before you can access the array. Therefore, when you are working with very large files, ReadLines can be more efficient. Example 1: File.ReadAllLines()

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

Example 2: File.ReadLines()

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

   //Do something     

}

Response for Sudhakar Tillapudi

Anirudha Gupta
  • 9,073
  • 9
  • 54
  • 79
Bradley
  • 455
  • 5
  • 11
  • 3
    Arguably should have marked question as _duplicate_ rather than quoting another answer –  Nov 24 '15 at 05:07
  • Maybe Micky, but the question was "Optimizing List" not diference between ReadALlLines and ReadLines – Bradley Nov 25 '15 at 16:58
0

Read Big TXT File, Out of Memory Exception

I just copied paste the solution from other question. See if it works.

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

ReadLines returns IEnumerable<string>.File.ReadLine

Concept is to not load all lines into a list at once. Even if you want to process them, process them line by line using IEnumerable instead of List.

Community
  • 1
  • 1
Ppp
  • 1,015
  • 9
  • 14
0

If the exception occurs at ReadAllLines, try this:

Use a StreamReader to read the file line by line and ad it to the list. Something like this:

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

If the exception occurs at ToList, try this:

You should get the array returned by ReadAllLines first, and use a foreach loop to add the array elements to the list.

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

If this still does not work, use the ReadLines method in the same class. The difference between ReaDAllLines and ReadLines is that the latter returns an IEnumerable<string> instead of a string[]. An IEnumerable<string> use deferred execution. It will only give you one element when you ask it to. Jon Skeet's book, C# In Depth talks about this in detail.

Here is the docs for ReadLines for more information:

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

Sweeper
  • 213,210
  • 22
  • 193
  • 313