C#ファイルの一覧を取得しLinqで加工してみる。

C# コンピュータ
C#

System.IO.Directoy.EnumerateFiles(<String>)を使うとディレクトリ内のファイルの一覧を取得することが出来ます。戻り値はIEnumerable<String>型でforeach出来る配列なような代物です。

ファイルの一覧をLinqを使い加工してみたいと思います。

なお、対象ディレクトリには以下のファイルがあることとします。

ファイルの一覧

 var files = Directory.EnumerateFiles(path);

結果

.\test\1.txt
.\test\2.txt
.\test\3.txt
.\test\4.txt
.\test\5.csv

要素の有無

files.Any()

結果

files要素有り

要素の有無を確認する場合.Count()が0以上かチェックする代わりにこちらを使う。

要素数の取得

files.Count()

結果

filesの要素数:5

ちなみに配列の要素数はLength

最初(最後)の一件を取得

var files2 = files.First();
var files3 = files.Last();

結果

最初の要素:.\test\1.txt
最後の要素:.\test\5.csv

条件による絞り込み

var files4 = files.Where(x => Regex.IsMatch(x, @"[1|3|5]\.", RegexOptions.IgnoreCase));

結果

条件による絞り込み
.\test\1.txt
.\test\3.txt
.\test\5.csv

並べ替え

var files5 = files.OrderByDescending(x => x);

結果

.\test\5.csv
.\test\4.txt
.\test\3.txt
.\test\2.txt
.\test\1.txt

昇順は.OrderBy()

項目を追加

var files6 = files.Select(x => new {Path = x, Size = (new FileInfo(x)).Length});

結果

Path:.\test\1.txt Size:22
Path:.\test\2.txt Size:0
Path:.\test\3.txt Size:2139
Path:.\test\4.txt Size:2022
Path:.\test\5.csv Size:0

ファイルサイズの項目を追加してみる。
実際ファイルサイズなどの情報も取得したい場合はDirectory.EnumerateFilesではなくDirectoryInfo.EnumerateFilesを使う。

一連の処理をつなげる


var files7 = Directory.EnumerateFiles(path)
     .Select(x => new {Path = x, Size = (new FileInfo(x)).Length})
     .Where(x => x.Size > 0)
     .OrderByDescending(x => x.Size)
     .ThenBy(x => x.Path);

結果

Path:.\test\3.txt Size:2139
Path:.\test\4.txt Size:2022
Path:.\test\1.txt Size:22

配列に変換

var files8 = files.ToArray();

結果

files8:System.String[]

List<string>に変換

var files9 = new List<string>(files);

結果

files9:System.Collections.Generic.List`1[System.String]

実行可能なサンプルソース

// 
// Directory.EnumerateFilesとLinqのサンプル
// 
using System;
using System.Collections.Generic;
using System.Linq;

using System.IO;

using System.Text.RegularExpressions;


// コンパイル
// csc Linq.cs

class LinqSample
{
    // エントリーポイント
    static void Main()
    {
        var path = @".\test";

        // ファイルの一覧
        var files = Directory.EnumerateFiles(path);
        Console.WriteLine("ファイルの一覧");
        foreach(var f in files)
        {
            Console.WriteLine("{0}", f);
        }

        // 要素の有無
        if (files.Any())
        {
            Console.WriteLine("files要素有り");
        }
        else
        {
            Console.WriteLine("files要素無し");            
        }

        // 要素数の取得
        Console.WriteLine("filesの要素数:{0}",files.Count());

        // 最初の一件を取得
        var files2 = files.First();
        Console.WriteLine("最初の要素:{0}", files2);

        // 最後の一件を取得
        var files3 = files.Last();
        Console.WriteLine("最後の要素:{0}", files3);

        // 条件による絞り込み
        var files4 = files.Where(x => Regex.IsMatch(x, @"[1|3|5]\.", RegexOptions.IgnoreCase));
        Console.WriteLine("条件による絞り込み");
        foreach(var f in files4)
        {
            Console.WriteLine("{0}", f);
        }

        // 並べ替え
        var files5 = files.OrderByDescending(x => x);
        Console.WriteLine("降順で並べ替え");
        foreach(var f in files5)
        {
            Console.WriteLine("{0}", f);
        }

        // 項目を追加
        var files6 = files.Select(x => new {Path = x, Size = (new FileInfo(x)).Length});
        Console.WriteLine("項目の追加");
        foreach(var f in files6)
        {
            Console.WriteLine("Path:{0} Size:{1}", f.Path, f.Size);
        }

        // 一連の処理をつなげる
        var files7 = Directory.EnumerateFiles(path)
            .Select(x => new {Path = x, Size = (new FileInfo(x)).Length})
            .Where(x => x.Size > 0)
            .OrderByDescending(x => x.Size)
            .ThenBy(x => x.Path);
        
        Console.WriteLine("一連の処理をつなげる");
        foreach(var f in files7)
        {
            Console.WriteLine("Path:{0} Size:{1}", f.Path, f.Size);
        }

        // 配列に変換
        var files8 = files.ToArray();
        Console.WriteLine("files8:{0}",files8.GetType());

        // List<string>に変換
        var files9 = new List<string>(files);
        Console.WriteLine("files9:{0}",files9.GetType());

    }
}

Linqで自分が使いそうな機能をまとめてみました。
Linqを使うと一連の手続きをシンプルに記述することが出来ます。出来ますがシンプルに物事が進められない場面も数多くあると思いますので、無理して使う必要は無いと思います。

個人的にお気に入りなのは.Any()です。

コメント