ホーム > .NET, LINQを楽しむ > LINQを使ってフォルダやファイルの情報を集積する

LINQを使ってフォルダやファイルの情報を集積する

久しぶりにLINQ(LINQ to Object)ネタです。
ここ2、3日で知り合いの方のBlogに続けてこのような話があがってたもので、ちょっと試したことまとめておこうかと(w

LINQ to Objectで一番重要なのは、操作しようとするデータをいかにしてIEnumerableな形にするか、ということだと思っています。
特にフォルダやファイルといった階層構造のデータを扱う場合、そこさえできてしまえば後はどうにでもなります。
そんな意味で、すごい、と思ったのが@ITの記事に載っていた以下のコードです。

IEnumerable<FileInfo> fileList = Directory.GetFiles(startFolder, "*.*", SearchOption.AllDirectories).Select(x => new FileInfo(x));

このコード自体Selectメソッドを使ったLINQのコードなのですが、この1行でstartFolderに指定したフォルダ以下の全てのファイルをサブフォルダ配下のものを含めてFileInfoオブジェクトとしてIEnumerableなものにしてしまっています。
FileInfoオブジェクトであればそのファイルのすべての情報にアクセスできますから、あとはここでつくったfileListに対してどのような操作を行うかを考えるだけでよい、ということになります。

ではまず最初に、このコードをベースに、指定したフォルダが使用している容量を計算してみましょう。

—————————————————————————————————————–
using System;
using System.Linq;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        string startFolder = @"c:\temp\";

        Console.WriteLine("トータルバイト数:{0}",
                          Directory.GetFiles(startFolder, "*.*", SearchOption.AllDirectories)
                              .Select(x => new FileInfo(x)).Sum(f => f.Length));

        Console.Read();
    }
}
—————————————————————————————————————–

先ほどのコードで取り出したすべてのファイルのバイト数(f.Length)をSumメソッドで合計することで容量を計算してます。
実質的に1行で済んでますね。

フォルダ、サブフォルダ毎に情報をまとめたい、といったときにはgroup byを使うと便利です。
フォルダ毎にそこに含まれているファイルを取り出し、作成日順に並べてみましょう。

—————————————————————————————————————–
using System;
using System.Linq;
using System.IO;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        string startFolder = @"c:\temp\";

        IEnumerable<FileInfo> fileList = Directory.GetFiles(startFolder, "*.*",
  SearchOption.AllDirectories).Select(x => new FileInfo(x));

        var query = from f in fileList
                    orderby f.CreationTime
                    group f by f.DirectoryName;

        foreach (var item in query)
        {
            Console.WriteLine("フォルダ名:{0}", item.Key);
            foreach (var f in item)
            {
                Console.WriteLine("{0}:{1}", f.CreationTime, f.Name);
            }
        }
        Console.Read();
    }
}
—————————————————————————————————————–

こんな感じでDirectoryNameを利用してグループ化することでフォルダ毎に情報をまとめることができます。

基本的に、最初の一行のコードの意味がわかっていれば、あとはいろんな応用がききます。
このようなコードを提示してくれた川俣さんにほんと感謝です。

カテゴリー:.NET, LINQを楽しむ
  1. まだコメントはありません。
  1. No trackbacks yet.

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。