0

I am trying to read a large number of files and to store some information in a dictionary. My complete code is:

[HttpGet("[action]")]

public JsonResult GenerateMapFiles()
{
    Dictionary<string, List<Tuple<string, ushort>>>[] CodeMapping = new Dictionary<string, List<Tuple<string, ushort>>>[256];

    /* Pre-creating some dictionaries */
    CodeMapping[2] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[8] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[16] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[32] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[64] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[128] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[256] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);

    string[] fileList = System.IO.Directory.GetFiles("C:\\mySQL");

    /* Processing code was here, but I commented it and it is still generating exception */

    return Json(CodeMapping);
}

The line string[] fileList = System.IO.Directory.GetFiles("C:\\mySQL"); raises an exception:

Exception thrown: 'System.IndexOutOfRangeException' in XXXXX.dll: 'Index was outside the bounds of the array.'

If I comment the CodeMapping[X] assignments, there is no error and fileList is populated. I do not understand why the previous lines impact this one. Would someone be able to explain to me why?

Keyur Ramoliya
  • 1,900
  • 2
  • 16
  • 17
Valentin
  • 81
  • 6
  • 5
    Isn't this line `CodeMapping[256] = new ...` throwing the exception? You initialized `CodeMapping` with 256 elements, and indexes go from 0 to 255, therefore `CodeMapping[256]` is out of bounds – Rafalon Jul 11 '18 at 09:01
  • `CodeMapping` is declared to have 256 elements. These are numbered 0-255. Element 256, which you attempt to access, is out of bounds. Why you've been misled to the source of the error we couldn't say. – Damien_The_Unbeliever Jul 11 '18 at 09:03
  • If you have seen the `System.IO.Directory.GetFiles` function throwing exceptions it hasnt the `ArrayOutOfBoundsException` so the error is what top comments say. – Azhy Jul 11 '18 at 09:05
  • Tim, this is an array of Dictionary, the int is the index array. Rafalon, yes you are perfectly correct. I do not really understand why the debugger pointed out the wrong line thought. – Valentin Jul 11 '18 at 09:06
  • Possible duplicate of [What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?](https://stackoverflow.com/questions/20940979/what-is-an-indexoutofrangeexception-argumentoutofrangeexception-and-how-do-i-f) – Mong Zhu Jul 11 '18 at 09:06
  • Sometime debuggers may say a wrong line number because of slowing computer or changing code while debugging or something else. – Azhy Jul 11 '18 at 09:08

2 Answers2

0

Ok I found the solution while submitting, it is apparently a bug of Visual Studio not pointing the correct line in debugging mode. My first line should have been :

Dictionary<string, List<Tuple<string, ushort>>>[] CodeMapping = new Dictionary<string, List<Tuple<string, ushort>>>[257];
Valentin
  • 81
  • 6
  • This is only a solution if you *intended* to create an array of 257 items, which would be unusual. More commonly, the intent would have been to create an array of 256 items and the fix is to correct your indexing from being 1-based to being 0-based. – Damien_The_Unbeliever Jul 11 '18 at 09:33
  • Hi Damien, I am reading millions of already existing files, with values indexed between 1 and 256, that is why, in this specific case, allocating a larger array is easier and has better performance. – Valentin Jul 11 '18 at 11:07
0

I think you should create dictionaries on n-1 locations as maximum index will go from 0 to 255 in case of a collection of 256 elements.

so you re-write this as:

/* Pre-creating some dictionaries */
    CodeMapping[1] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[7] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[15] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[31] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[63] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[127] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
    CodeMapping[255] = new  Dictionary<string, List<Tuple<string, ushort>>>(256);
Gaurav Jalan
  • 467
  • 2
  • 14
  • I am reading more than 10 billion lines, that contains either 1,2,8,16,32,64,128,256. Substracting 1 for each line read is more time consuming compared to preallocating a large array, even if I only use 8 index of this array. But I am totally open if there is a cleaner solution. – Valentin Jul 11 '18 at 11:01
  • Increase the length of array to 257 then instead of 256 :) – Gaurav Jalan Jul 12 '18 at 05:32