按名称排序 FileSystemInfo[]

Posted

技术标签:

【中文标题】按名称排序 FileSystemInfo[]【英文标题】:Sort FileSystemInfo[] by Name 【发布时间】:2012-03-13 10:49:38 【问题描述】:

我可能已经花了大约 500 个小时在谷歌上搜索并阅读 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);

【问题讨论】:

在您的场景中是否可以更改文件名模式?例如。从 1.png 到 01.png? 试试这个***.com/questions/1601834/…,StrCmpLogicalW 是 Windows API,它以“逻辑”方式对文件名进行排序。 【参考方案1】:

这不是文件长度的问题,而是按字典顺序比较名称的问题。

听起来在这种特殊情况下,您想要获取不带扩展名的名称,尝试将其解析为整数,然后以这种方式比较两个名称 - 如果失败,您可以退回到字典顺序。

当然,如果你有 "debug1.png,debug2.png,...debug10.png"...你需要一个更复杂的算法。

【讨论】:

【参考方案2】:

您将名称作为字符串进行比较,即使(我假设)您希望它们按数字排序。

这是一个众所周知的问题,即“10”在“9”之前,因为 10 (1) 中的第一个字符小于 9 中的第一个字符。

如果您知道文件都包含编号的名称,您可以修改自定义排序例程以将名称转换为整数并适当地对它们进行排序。

【讨论】:

【参考方案3】:

您的代码正确且按预期工作,只是排序是按字母顺序执行的,而不是按数字顺序执行的。

例如,字符串“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);

【讨论】:

【参考方案4】:

我遇到了同样的问题,但我没有自己对列表进行排序,而是使用 6 位“0”填充键更改了文件名。

我的列表现在看起来像这样:

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

但是,如果您不能更改文件名,您将不得不实现自己的排序例程来处理 alpha 排序。

【讨论】:

【参考方案5】:

使用一些 linq 和正则表达式来修复排序怎么样?

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 => newfsi, 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?

【讨论】:

以上是关于按名称排序 FileSystemInfo[]的主要内容,如果未能解决你的问题,请参考以下文章

Unix 的 'ls' 按名称排序

使用 jquery 按名称和数组值选择

c++ 按字母顺序排序名称

使用 Linq 按名称频率对列表进行排序

Elasticsearch 列表索引按名称排序

php WooCommerce |按名称添加按商店归档排序