C# 使用自然顺序从文件夹加载文件

C# 使用自然顺序从文件夹加载文件,c#,C#,在一个文件夹中,我有这些文件。windows资源管理器上的顺序为: 输入(1).jpg 输入(2).jpg 输入(101).jpg 这是我从文件夹中获取文件的方式: var files = Directory.GetFiles(inputImage, "*.*", SearchOption.TopDirectoryOnly); 但命令是: 输入(1).jpg 输入(101).jpg 输入(2).jpg 甚至我也尝试过:Array.Sort(文件) 但顺序是一样的,我如何按此顺序加载文件

在一个文件夹中,我有这些文件。windows资源管理器上的顺序为:

  • 输入(1).jpg
  • 输入(2).jpg
  • 输入(101).jpg
这是我从文件夹中获取文件的方式:

var files = Directory.GetFiles(inputImage, "*.*", SearchOption.TopDirectoryOnly);
但命令是:

  • 输入(1).jpg
  • 输入(101).jpg
  • 输入(2).jpg
甚至我也尝试过:
Array.Sort(文件)

但顺序是一样的,我如何按此顺序加载文件:

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

您需要实现自己的比较,以“意识到”两个字符串包含嵌入的非零填充数字的方式来比较两个字符串。Explorer已经包含此逻辑,并且(根据注释)它在
strmplogicalw
中公开,您可以在自定义
比较器
实现中调用它,您可以将其传递给排序方法

如果您了解名称(即模式)的所有其他信息,那么很容易去掉固定部分进行比较,但是
strmplogicalw
将为您提供一个很好的通用实现


当然,如果您可以控制创建文件的内容,一种更简单的方法是将文件名归零到合理的位数,例如5或6。

您需要实现自己的比较,以“意识到”两个字符串包含嵌入的非零填充数字的方式来比较两个字符串。Explorer已经包含此逻辑,并且(根据注释)它在
strmplogicalw
中公开,您可以在自定义
比较器
实现中调用它,您可以将其传递给排序方法

如果您了解名称(即模式)的所有其他信息,那么很容易去掉固定部分进行比较,但是
strmplogicalw
将为您提供一个很好的通用实现


当然,如果您可以控制创建文件的任何内容,一种更简单的方法是将文件名归零到合理的位数,例如5或6。

如果是我,我将创建一个dictionary对象,并将第一个值存储为原始文件名,第二个值存储为您需要处理的自定义文件名

例如,dictionary对象的外观如下所示:

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

然后,您可以对第二个字段进行排序,但从dictionary对象的第一个字段中提取文件名。

如果是我,我将创建一个dictionary对象,并将第一个值存储为原始文件名,将第二个值存储为您需要处理的自定义文件名

例如,dictionary对象的外观如下所示:

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

然后您可以在第二个字段上排序,但从dictionary对象的第一个字段中提取文件名。

请记住数组。默认情况下,排序(文件)是将文件名按文本而不是数字排序。请尝试解析数字,然后按数字排序。

请记住数组。默认情况下,排序(文件)是将文件名按文本排序,而不是按数字排序。尝试解析数字,然后按这些数字排序。

您可以使用OrderBy扩展名,更多详细信息请参见此处

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

var files = Directory.GetFiles(inputImage, "*.*", SearchOption.TopDirectoryOnly).OrderBy(t => t);
如果你只想按数字排序,你可以做一些聪明的字符串替换,比如

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

您可以使用OrderBy扩展,更多详细信息请参见此处

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

var files = Directory.GetFiles(inputImage, "*.*", SearchOption.TopDirectoryOnly).OrderBy(t => t);
如果你只想按数字排序,你可以做一些聪明的字符串替换,比如

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

好吧,我来试试这样的:

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

我很确定一定有一种有效的方法可以做到这一点,但只要我的两分钱。

好吧,我会试试这样的方法:

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

我很确定一定有一种有效的方法可以做到这一点,但只要我的两分钱。

如果您以简单的方式加载文件:

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;
}
具有比较功能:

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;
}

如果以简单的方式加载文件:

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;
}
具有比较功能:

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;
}
这会有帮助

我将把代码复制到这里

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);
    }
}
公共静态类MyExtensions
{
公共静态IEnumerable CustomSort(此IEnumerable列表)
{
int maxLen=list.Select(s=>s.Length.Max();
返回列表。选择(s=>new
{
OrgStr=s,
SortStr=Regex.Replace(s,@“(\d+)|(\d+)”,m=>m.Value.PadLeft(maxLen,char.IsDigit(m.Value[0])?“”:“\xfff”)
})
.OrderBy(x=>x.SortStr)
.选择(x=>x.OrgStr);
}
}
这会有所帮助

我将把代码复制到这里

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);
    }
}
公共静态类MyExtensions
{
公共静态IEnumerable CustomSort(此IEnumerable列表)
{
int maxLen=list.Select(s=>s.Length.Max();
返回列表。选择(s=>new
{
OrgStr=s,
SortStr=Regex.Replace(s,@“(\d+)|(\d+)”,m=>m.Value.PadLeft(maxLen,char.IsDigit(m.Value[0])?“”:“\xfff”)
})
.OrderBy(x=>x.SortStr)
.选择(x=>x.OrgStr);
}
}

Natural sorting Natural sorting不确定它的浏览器使用的是什么,但Win32的strmplogicW会给出所需的顺序不确定它的浏览器使用的是什么,但Win32的strmplogicW会给出所需的顺序我在Replace(“.jpg”,”)中尝试了这个方法,但它不起作用:pAh,应该将它转换为int,例如OrderBy(t=>int.Parse(t.Replace(“input”,“input”).Replace((“,”).Replace(“),”).Trim());实际上,您可以使用正则表达式获取数字,并对其进行排序。我在Replace(“.jpg”,“input”)中尝试了此方法,但不起作用:pAh,应该将其强制转换为int,例如.OrderBy(t=>int.Parse(t.Replace(“input”,“input”).Replace(“,”).Replace(“),”).Replace(“),”).Trim()));真的,