2012-06-18 50 views
1

在一个文件夹中,我有这些文件。上Windows资源管理器的命令是:从一个文件夹使用自然顺序加载文件

  • 输入(1).JPG
  • 输入(2).JPG
  • 输入(101).JPG

这是我得到的方式从文件夹中的文件:

var files = Directory.GetFiles(inputImage, "*.*", SearchOption.TopDirectoryOnly); 

但顺序将是:

  • 输入(1).JPG
  • 输入(101).JPG
  • 输入(2).JPG

即使我的尝试:Array.Sort(files);

但顺序是相同的,如何可以装入与此顺序文件:

  • 输入(1).JPG
  • 输入(2).JPG
  • 输入(101).jpg

在此先感谢。

+1

自然排序http://www.codinghorror.com/blog/2007/12/sorting- for-humans-natural-sort-order.html – Mr47

回答

2

一些一些聪明的字符串替换嗯,我会尝试这样的事:

 var files = from file in directoryInfo.EnumerateFiles() 
     .Where(f => f.Extension == ".jpg") 
        orderby ExtractNumber(file.Name) ascending 
        select file.FullName; 
     return files.ToList<string>(); 

在这里,我们提取(和) - 之间的文件编号。

private static object ExtractNumber(string p) 
{ 
    int lenght = p.IndexOf(')') - p.IndexOf('('); 
    return int.Parse(p.Substring(p.IndexOf('('), lenght - 1)); 
} 

我很确定必须有一个有效的方法来做到这一点,但只是我的两分钱。

2

您需要实现自己的比较,以“实现”它们包含嵌入的非零填充数字的方式比较两个字符串。 Explorer已经包含了这个逻辑,并且(根据评论),这在StrCmpLogicalW中公开,您可以在Comparer<string>自定义实现中调用P/Invoke,您可以将它传递给排序方法。

如果你知道关于名称(即模式)的所有信息,那么很容易就可以去除固定部分进行比较 - 但StrCmpLogicalW会给你一个很好的通用实现。

当然,如果您控制创建文件的任何内容,则更简单的方法是将文件名零填充到合理数量的数字,例如, 5或6.

+0

不知道它的资源管理器使用什么,但Win32的StrCmpLogicalW会给出所需的订单 –

+0

@AlexK .:非常感谢。将编辑。 –

1

如果是我,我会创建一个字典对象并将第一个值存储为原始文件名,将第二个值存储为您需要按摩的自定义文件名。

所以,举例来说,Dictionary对象会是这个样子:

input (1).jpg | input (001).jpg 
input (2).jpg | input (002).jpg 
input (101).jpg | input (101).jpg 

然后你就可以排序的第二场,但在字典对象从第一场拉的文件名。

2

请记住,Array.Sort(文件)默认情况下将文件名称排序为文​​本,而不是数字。尝试解析数字,然后排序。

1

您可以使用OrderBy扩展,更多的细节在这里http://msdn.microsoft.com/en-us/library/bb534966.aspx

这是一个简单的lambda表达式的T => t部。如果需要,可以在进行排序之前进行一些操作。

var files = Directory.GetFiles(inputImage, "*.*", SearchOption.TopDirectoryOnly).OrderBy(t => t); 

如果你想只对数量进行排序,你可以像

.OrderBy(t => t.Replace("input", "").Replace("(", "").Replace(")","").Trim()); 
+0

也许添加.Replace(“。jpg”,“”)以及 – Breland

+0

我在Replace(“。jpg”,“”)中试过这个,但它不起作用:p – olidev

+0

结果是一样的 – olidev

2

如果您加载一个简单的方法中的文件:

string[] files = Directory.GetFiles ("folder"); 

,并假设总是有括号内的数字,你可以使用一个函数:

Array.Sort (files, compareFilesWithBrackets); 

与比较功能:

public static int compareFilesWithBrackets (string arg1, string arg2) 
{ 
     string filename1 = System.IO.Path.GetFileName (arg1); //extract filename from the path of the first file 
     string filename2 = System.IO.Path.GetFileName (arg2); // extract second file filename 
     Match m = Regex.Match (filename1, "\\(([0-9]+)\\)"); // check if there is (number) for file 1 
     int file1 = 0; // if no number leave 0 
     if (m.Success) { // else if success parse the number from brackets 
      file1 = int.Parse (m.Groups [1].Value); 
     } 
     m = Regex.Match (filename2, "\\(([0-9]+)\\)"); 
     int file2 = 0; 
     if (m.Success) { 
      file2 = int.Parse (m.Groups [1].Value); 
     } 
     return file1 - file2; 
} 
1

This CustomSort can help

List<string> list = new List<string>() 
{ 
    "input (1).jpg","input (101).jpg", "input (11).jpg", "input (2).jpg" 
}; 

var sortedList = list.CustomSort().ToList(); 

输出将是:

input (1).jpg 
input (2).jpg 
input (11).jpg 
input (101).jpg 

我会在这里复制的代码

public static class MyExtensions 
{ 
    public static IEnumerable<string> CustomSort(this IEnumerable<string> list) 
    { 
     int maxLen = list.Select(s => s.Length).Max(); 

     return list.Select(s => new 
     { 
      OrgStr = s, 
      SortStr = Regex.Replace(s, @"(\d+)|(\D+)", m => m.Value.PadLeft(maxLen, char.IsDigit(m.Value[0]) ? ' ' : '\xffff')) 
     }) 
     .OrderBy(x => x.SortStr) 
     .Select(x => x.OrgStr); 
    } 
} 
相关问题