4

我对 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# 中的一些订单功能吗?

4

2 回答 2

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 和更高版本中可用)。

于 2013-02-26T08:30:36.220 回答
2

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

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

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是为了防止在文件名中没有日期部分的文件时出现错误。下一个选择解析DateTime来自 的标记string.Split。最后三个部分包含年、月和日。OrderBy将按日期订购。最后我再次选择完整路径,因为您最初想要订​​购文件。

foreach您可以使用 a或使用枚举结果,例如ToList,如果您想保留它:

foreach (string f in files)
{
    // ...
}
于 2013-02-26T08:30:42.193 回答