Search code examples
c#icomparersortedsetgeneric-collections

SortedSet add confusion


When I run the code below only 8 of the 50 files in the directory get added.

The files are named like 0001, 0002, 0003, 0004, etc.

The files that get added are in this order: 7,0,1,2,3,4,5,6 when items are no longer added.

Looking at my SortedSet's Min and Max values are 6 and 7 respectively.

I suppose my question is there a better way to do this or a way to get the below code to do what I want. To be more specific i want the file path strings to be sorted in a collection based on the parsed values in the file.

string[] files = System.IO.Directory.GetFiles(textBox1.Text);

SortedSet<string> ascending = new SortedSet<string>(new MyComparer());

foreach (string f in files)
{
    bool added = ascending.Add(f);
}

//Compares values in file format
//MyComparer.Compare:
using (FileStream fsx = new FileStream(x, FileMode.Open, FileAccess.Read, FileShare.Read))
using (FileStream fsy = new FileStream(y, FileMode.Open, FileAccess.Read, FileShare.Read))
using (StreamReader rx = new StreamReader(fsx))
using (StreamReader ry = new StreamReader(fsy))
{
    //the first 6 bytes represent a number
    char[] buffx = new char[6], buffy = new char[6];
    rx.Read(buffx, 0, 6);
    ry.Read(buffy, 0, 6);

    int nx, ny;
    if (!int.TryParse(new String(buffx), out nx))
        throw new Exception("Wtf?");
    if (!int.TryParse(new String(buffy), out ny))
        throw new Exception("Wtf?");

    return Comparer<int>.Default.Compare(nx, ny);
}

Solution

  • I'd write your code similar to this:

    int GetFileContentNumber(string filename)
    {
      using(var reader=new StreamReader(filename)
      {
        char[] chars=new char[6];
        reader.Read(buf, 0, 6);
        return int.Parse(new String(chars));
    
      }
    }
    
    IEnumerable<string> files = System.IO.Directory.GetFiles(textBox1.Text)
        .Select(filename=>new KeyValuePair<string,int>(filename, GetFileContentNumber(filename)))
        .OrderBy(pair=>pair.Value)
        .Select(pair=>pair.Key);
    

    But I haven't tested it. So it might still have bugs.