按特定顺序迭代文件夹中的文件?

时间:2013-02-26 08:15:14

标签: c# loops

我对c#编程很新,所以如果我的问题很简单,我会道歉。 我正在运行一些c#代码,我需要迭代文件夹中的一些文件并使用:

foreach (string f in Directory.GetFiles(@"C:\temp\GeneralStats"))
{

但是,我想根据文件名以特定顺序读取这些文件。我的文件名格式如下。

generalstats_2012_11_1.csv
generalstats_2012_11_2.csv
generalstats_2012_11_3.csv
.....

当我的代码读入文件时,它会以generalstats_2012_11_1.csv开头,但会直接跳转到generalstats_2012_11_10.csv,而不是generalstats_2012_11_2.csv。

我尝试在网上搜索答案,但一直找不到。我当然按照特定文件夹中的日期(名称)命令文件,但代码根本不承认。 任何人都可以帮助我 - 我错过了c#中的一些订单功能吗?

2 个答案:

答案 0 :(得分:2)

您可以使用:

        var paths = Directory.GetFiles(@"C:\temp\GeneralStats")
            .OrderBy(path => 
                Convert.ToInt32(path.Split('_', '.')[1]) * 10000 + 
                Convert.ToInt32(path.Split('_', '.')[2]) * 100 + 
                Convert.ToInt32(path.Split('_', '.')[3]));

        foreach (string path in paths)
        {
        }

这从文件名中获取日期部分并从中创建一个整数,例如文件名中的2012_11_10为2012110为整数,2012_11_1为20121101等。这些数字用于排序

上述方法的另一种变体是:

        var paths = Directory.GetFiles(@"C:\temp\GeneralStats")
            .OrderBy(path =>
                Convert.ToInt32(
                    String.Concat(
                        path.Split('_', '.')
                            .Skip(1)
                            .Take(3)
                            .Select(num => num.PadLeft(2, '0'))
                            .ToArray())
                )
            );

它还解析文件名中的数字并创建用于排序的整数。

您可以使用Directory.GetFiles代替Directory.EnumerateFiles方法(但这仅适用于.NET 4及更高版本)。

答案 1 :(得分:2)

如果您想按文件名后面的日期订购,则必须将其转换为一个,否则订单按字母顺序排列(因此“10”在“2”之前)。

您可以在此linq查询中使用Enumerable.OrderBy

var files = Directory.EnumerateFiles(@"C:\temp\GeneralStats", "*.csv")
    .Select(fn => new
    {
        Path = fn,
        Split = Path.GetFileNameWithoutExtension(fn).Split('_')
    })
    .Where(x => x.Split.Length == 4)
    .Select(x => new
    {
        x.Path,
        Date = new DateTime(int.Parse(x.Split[1]), int.Parse(x.Split[2]), int.Parse(x.Split[3]))
    })
    .OrderBy(x => x.Date)
    .Select(x => x.Path);

首先,我选择的匿名类型包含Path类中的一些有用属性,例如GetFileNameWithoutExtension。这将使查询的其余部分更有效,更可读。 Where用于防止文件名中没有日期部分的文件时出错。下一个select从DateTime派生的标记中解析string.Split。最后三部分包含年,月和日。 OrderBy将按日期排序。最后,我再次选择完整路径,因为您最初想要订​​购文件。

您可以使用foreach枚举结果或使用例如ToList如果你想坚持下去:

foreach (string f in files)
{
    // ...
}