Odd System.IndexOutOfRangeException when trying to overwrite .txt file c#

200 views Asked by At

I want to extend a data collection in a .txt file.

I'm reading a .txt file into a string array. Then I'm making a new string array with 5 more elements.

string oldarray[] = File.ReadAllLines(targetfile);   //it is correctly reading the file
string newarray[] = new string[oldarray.Count()+5];

for (int i = 0; i < oldarray.Count(); i++) {         //copy old array into new bigger one
    newarray[i] = oldarray[i];
}
newarray[oldarray.Count() + 1] = "Data1";  //fill new space with data
newarray[oldarray.Count() + 2] = "Data2";
newarray[oldarray.Count() + 3] = "Data3";
newarray[oldarray.Count() + 4] = "Data4";
newarray[oldarray.Count() + 5] = " ";     //spacer

//now write new array into same textfile over old data
File.WriteAllLines(targetfile, newarray);  //System.IndexOutOfRangeException

I also tried writing line by line to the file like so, but it did just spit out the same exception:

using (StreamWriter writer = new StreamWriter(destinationFile)) //System.IndexOutOfRangeException 
{
    for (int i = 0; i < newarray.Length; i++)
    {
        writer.WriteLine(newarray[i]);
    }
}

Why does it do that, and how do I fix it?

3

There are 3 answers

0
Panagiotis Kanavos On

Array indexes are zero-based so oldarray.Count() + 5 points to an element after the end of the array. The first element is left empty too.

This could be fixed by fixing the indexes to be between 0 and 4 instead of 1 and 5. A better solution though would be to load the lines as a list and append the new strings :

string lines = File.ReadLines(targetfile).ToList();
var newLines=new[] {"Data1","Data2"...};
lines(newLines);
File.WriteAllLines(targetfile, lines);

Or even

var newLines=....;
string lines = File.ReadLines(targetfile)
                   .Concat(newLines)
                   .ToList();
File.WriteAllLines(targetfile, lines);

ReadAllLines uses a List as well and returns a copy of the list as an array. ReadLines on the other hand, returns lines one at a time as an IEnumerable<string>. The file remains open as long as the IEnumerable is iterated, so we need ToList() to consume it and allow the file to close before overwriting it.

0
Mureinik On

You're off by one - the last element in olaArray is at oldarray.Count() - 1, not oldarray.Count()

for (int i = 0; i < oldarray.Count(); i++){         //copy old array into new bigger one
    newarray[i] = oldarray[i];
}
newarray[oldarray.Count()]     = "Data1";  //fill new space with data
newarray[oldarray.Count() + 1] = "Data2";
newarray[oldarray.Count() + 2] = "Data3";
newarray[oldarray.Count() + 3] = "Data4";
newarray[oldarray.Count() + 4] = " ";     //spacer
0
Andrei Prigorshnev On

The index oldarray.Count() + 5 does not exist in your new array.

Array indexing starts from zero. If you have an array with 10 elements then the first index is 0 and the last index is 9. If you make a new array with oldarray.Count() + 5 items it'll have 15 items and the last index will be 14 (not oldArray.Count + 5 which equals 15).

Just do like this:

newarray[oldarray.Count()] = "Data1";
newarray[oldarray.Count() + 1] = "Data2";
newarray[oldarray.Count() + 2] = "Data3";
newarray[oldarray.Count() + 3] = "Data4";
newarray[oldarray.Count() + 4] = " ";