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_2.csvではなくgeneralstats_2012_11_10.csvに直接ジャンプします。

Webで回答を検索しようとしましたが、見つかりませんでした。もちろん、特定のフォルダー内の日付(名前内)に従ってファイルを並べ替えましたが、コードはそれをまったく認識していません。誰かが私を助けることができます-私が見逃した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、ファイル名は整数として2012_11_12012110、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-queryで使用できます。

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。最後の3つの部分には、年、月、日が含まれます。OrderBy日付で注文します。最初にファイルを注文したかったので、最後にフルパスを再度選択します。

結果をaで列挙するか、永続化する場合などにforeach使用できます。ToList

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