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);
}
}