2012-03-13 311 views
2

我可能花了大约500个小时使用谷歌搜索和阅读MSDN文档,它仍然拒绝按我想要的方式工作。按名称排序FileSystemInfo []

我可以通过名称文件进行排序是这样的:

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); 
} 
+0

是否可以在您的方案中更改文件名模式?例如。从1.png到01.png? – 2012-03-13 10:53:46

+1

试试这个http://stackoverflow.com/questions/1601834/c-implementation-of-or-alternative-to-strcmplogicalw-in-shlwapi-dll,'StrCmpLogicalW'是Windows API,它可以完成排序的“魔术”文件名以“逻辑”方式。 – xanatos 2012-03-13 11:00:05

回答

3

这不是文件长度特别的事情 - 这是名称的问题在词典顺序进行比较。

这听起来像是在这种特殊情况下,您希望获取没有扩展名的名称,尝试将其解析为一个整数,然后将这两个名称进行比较 - 如果失败,可以使用字典顺序。

当然,如果您有“debug1.png,debug2.png,... debug10.png”,那么这将不起作用......在这种情况下,您需要更复杂的算法。

0

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

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

你比较名称作为字符串,即使(我假设),你希望他们通过排序。

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

如果你知道文件将所有由编号名称组成,您可以修改自定义排序例程以将名称转换为整数并对其进行适当的排序。

0

我遇到了同样的问题,但我不是自己排序列表,而是使用6位'0'填充密钥更改了文件名。

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

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

但是,如果你不能改变文件名,你将不得不实现自己的排序例程来对付阿尔法排序。

0

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