我可能花了大约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);
}
这不是文件长度的问题,而是按字典顺序比较名称的问题。
在这种特殊的情况下,听起来你想获得没有扩展名的名称,试着将其解析为整数,并以这种方式比较这两个名称——如果失败,你可能会回到字典排序。
当然,如果你有"debug1.png,debug2.png,…debug10.png",这是行不通的……在这种情况下,你需要一个更复杂的算法。
您将名称比较为字符串,即使(我假设)您希望它们按数字排序。
这是一个众所周知的问题,"10"在"9"之前,因为10(1)中的第一个字符小于9中的第一字符。
如果您知道这些文件都将由带编号的名称组成,则可以修改自定义排序例程,将名称转换为整数,并对其进行适当排序。
您的代码是正确的,并且按预期工作,只是排序是按字母顺序执行的,而不是按数字执行的。
例如,字符串"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);
}
我遇到了同样的问题,但我没有自己对列表进行排序,而是使用6位数的"0"填充键更改了文件名。
我的列表现在看起来是这样的:
000001.jpg
000002.jpg
000003.jpg
...
000010.jpg
但是,如果不能更改文件名,就必须实现自己的排序例程来处理alpha排序
用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?