System.IO.DirectoryInfoを使用すると簡単にディレクトリ走査が出来ます。スクリプト言語の手軽さには敵わないですが、それでも結構楽です。
using System; using System.IO; using System.Text.RegularExpressions; namespace Mei { /// <summary> /// ファイル発見イベントを処理するメソッドを表します。 /// </summary> public delegate void FileFoundEventHandler(FileInfo fi); /// <summary> /// ディレクトリ発見イベントを処理するメソッドを表します。 /// </summary> public delegate void DirectoryFoundEventHandler(DirectoryInfo di); /// <summary> /// ディレクトリ走査を行うクラス。 /// </summary> public class DirectoryScanner { private Regex regex; private bool scanSubDir; /// <summary> /// ファイル発見イベント。 /// </summary> public event FileFoundEventHandler FileFound; /// <summary> /// ディレクトリ発見イベント。 /// </summary> public event DirectoryFoundEventHandler DirectoryFound; /// <summary> /// コンストラクタ。 /// </summary> public DirectoryScanner() : this(true) { } /// <summary> /// コンストラクタ。 /// </summary> /// <param name="scanSubDir">サブディレクトリを対象にするかを指定します。</param> public DirectoryScanner(bool scanSubDir) { this.scanSubDir =scanSubDir; } /// <summary> /// 指定したディレクトリを走査する。 /// </summary> /// <param name="path">走査対象となるディレクトリ。</param> /// <exception cref="System.IO.DirectoryNotFoundException">指定したディレクトリが存在しなかった場合、例外が発生する。</exception> public void Scan(string path) { regex = null; ExecuteScan(path); } /// <summary> /// 指定したディレクトリを走査し、パターンにマッチするファイルを探す。 /// </summary> /// <param name="path">検索対象となるディレクトリ。</param> /// <param name="pattern">マッチングする正規表現文字列。</param> /// <exception cref="System.IO.DirectoryNotFoundException">指定したディレクトリが存在しなかった場合、例外が発生する。</exception> public void Scan(string path, string pattern) { regex = new Regex(pattern); ExecuteScan(path); } /// <summary> /// ファイルがマッチするかどうかを判断する。 /// </summary> /// <param name="name">ファイル名。</param> /// <returns>マッチする場合はtrueを返す。</returns> private bool IsMatch(string name) { return regex == null || regex.IsMatch(name); } /// <summary> /// ディレクトリ走査を行う。 /// </summary> /// <param name="path">走査対象となるディレクトリ。</param> private void ExecuteScan(string path) { DirectoryInfo di = new DirectoryInfo(path); foreach (FileSystemInfo fsi in di.GetFileSystemInfos()) { if (IsMatch(fsi.Name)) { if (fsi is DirectoryInfo) { if (DirectoryFound != null) { // イベントの発火 DirectoryFound(fsi as DirectoryInfo); } } else { if (FileFound != null) { // イベントの発火 FileFound(fsi as FileInfo); } } } if (scanSubDir && fsi is DirectoryInfo) ExecuteScan(fsi.FullName); } } } }
using System; using System.IO; using System.Reflection; using Mei; /// <summary> /// DirectoryScannerテストサンプル /// </summary> class MyApp { private static int fileCount; private static int dirCount; static MyApp() { fileCount = 0; dirCount = 0; } static void NotifyFileFound(FileInfo fi) { fileCount++; Console.WriteLine("[File] {0}", fi.FullName); } static void NotifyDirectoryFound(DirectoryInfo di) { dirCount++; Console.WriteLine("[Dir] {0}", di.Name); } [STAThread] static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("usage : {0} serch_dir [pattern]", Assembly.GetEntryAssembly().GetName().Name); return; } DirectoryScanner ds = new DirectoryScanner(true); ds.FileFound += new FileFoundEventHandler(NotifyFileFound); ds.DirectoryFound += new DirectoryFoundEventHandler(NotifyDirectoryFound); try { if (args.Length == 1) ds.Scan(args[0]); else ds.Scan(args[0], args[1]); } catch (DirectoryNotFoundException e) { Console.WriteLine(e.Message); } Console.WriteLine("File={0}, Dir={1} found.", fileCount, dirCount); } }