Сортировать FileSystemInfo [] по имени - PullRequest
2 голосов
/ 13 марта 2012

Я, вероятно, потратил около 500 часов на поиски в Google и на чтение документации MSDN, и он по-прежнему отказывается работать так, как я хочу.

Я могу сортировать по именам такие файлы:

01.png
02.png
03.png
04.png

Т.е. у всех одинаковая длина файла.

Во-вторых, есть файл с большей длиной, все идет в ад.

Например, в последовательности:

1.png
2.png
3.png
4.png
5.png
10.png
11.png

Читается:

1.png, 2.png then 10.png, 11.png

Я не хочу этого.

Мой код:

DirectoryInfo di = new DirectoryInfo(directoryLoc);
FileSystemInfo[] files = di.GetFileSystemInfos("*." + fileExtension);
Array.Sort<FileSystemInfo>(files, new Comparison<FileSystemInfo>(compareFiles));

foreach (FileInfo fri in files)
{
    fri.MoveTo(directoryLoc + "\\" + prefix + "{" + operationNumber.ToString() + "}" + (i - 1).ToString("D10") +
        "." + fileExtension);

    i--;
    x++;
    progressPB.Value = (x / fileCount) * 100;
}

// compare by file name
int compareFiles(FileSystemInfo a, FileSystemInfo b)
{
    // return a.LastWriteTime.CompareTo(b.LastWriteTime);
    return a.Name.CompareTo(b.Name);
}

Ответы [ 6 ]

3 голосов
/ 13 марта 2012

Вы сравниваете имена как строки , хотя (я полагаю) вы хотите, чтобы они были отсортированы по числу .

Это хорошо известная проблема, когда «10» предшествует «9», потому что первый символ в 10 (1) меньше, чем первый символ в 9.

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

3 голосов
/ 13 марта 2012

Дело не в файле длина , в частности - речь идет о сопоставлении имен в лексикографическом порядке.

Похоже, что в данном конкретном случае вы хотите получить имя без расширения, попробуйте проанализировать его как целое число и сравнить таким образом два имени - в случае неудачи вы можете вернуться к лексикографическому упорядочению.

Конечно, это не сработает, если у вас есть "debug1.png, debug2.png, ... debug10.png" ... вам понадобится более сложный алгоритм в этом случае.

0 голосов
/ 13 марта 2012

Как насчет linq и regex, чтобы исправить порядок?

var orderedFileSysInfos = 
  new DirectoryInfo(directoryloc)
    .GetFileSystemInfos("*." + fileExtension)
    //regex below grabs the first bunch of consecutive digits in file name
    //you might want something different
    .Select(fsi => new{fsi, match = Regex.Match(fsi.Name, @"\d+")})
    //filter away names without digits
    .Where(x => x.match.Success)
    //parse the digits to int
    .Select(x => new {x.fsi, order = int.Parse(x.match.Value)})
    //use this value to perform ordering
    .OrderBy(x => x.order)
    //select original FileSystemInfo
    .Select(x => x.fsi)
    //.ToArray() //maybe?
0 голосов
/ 13 марта 2012

Я столкнулся с той же проблемой, но вместо того, чтобы самому сортировать список, я изменил имя файла, используя 6-значную клавишу «0».

Мой список теперь выглядит так:

000001.jpg
000002.jpg
000003.jpg
...
000010.jpg

Но если вы не можете изменить имена файлов, вам придется реализовать собственную процедуру сортировки, чтобы иметь дело с альфа-сортировкой.

0 голосов
/ 13 марта 2012

Возможно, эта статья на codeproject.com поможет вам: Числовая сортировка строк в C # .

0 голосов
/ 13 марта 2012

Ваш код правильный и работает как положено, просто сортировка выполняется по алфавиту, а не по номерам.

Например, строки «1», «10», «2» расположены в алфавитном порядке. Вместо этого, если вы знаете, что ваши имена файлов всегда просто число плюс «.png», вы можете выполнить сортировку численно. Например, что-то вроде этого:

int compareFiles(FileSystemInfo a, FileSystemInfo b)         
{             
    // Given an input 10.png, parses the filename as integer to return 10
    int first = int.Parse(Path.GetFileNameWithoutExtension(a.Name));
    int second = int.Parse(Path.GetFileNameWithoutExtension(b.Name));

    // Performs the comparison on the integer part of the filename
    return first.CompareTo(second);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...