C#でDirectoryを使いこなす方法|フォルダ作成・存在確認・削除・ファイル取得まで徹底解説

はじめに

C#でフォルダやファイルを操作する際に中心となるのが、System.IO名前空間に用意されているDirectoryクラスです。

Directoryクラスを使用すると、次のような処理を簡単に実装できます。

  • フォルダを新規作成する

  • フォルダが存在するか確認する

  • フォルダを削除する

  • 指定したフォルダ内のファイルを取得する

  • サブフォルダを含めてファイルを検索する

  • フォルダ一覧を取得する

この記事では、C#のDirectoryクラスについて、基本的な使い方から実践的なファイル検索まで、サンプルコードを交えて解説します。

1. C#のDirectoryクラスとは

Directoryは、フォルダを操作するための静的クラスです。

インスタンスを生成する必要がなく、次のようにクラス名から直接メソッドを呼び出します。

C#
Directory.CreateDirectory(@"C:\Sample");

フォルダの作成や存在確認、削除、ファイル一覧の取得など、フォルダに関係する処理を簡潔に記述できるのが特徴です。

1-1. Directoryクラスでできること

Directoryクラスには、主に次のようなメソッドが用意されています。

メソッド処理内容
CreateDirectoryフォルダを作成する
Existsフォルダが存在するか確認する
Deleteフォルダを削除する
GetFilesファイル一覧を配列として取得する
EnumerateFilesファイルを列挙しながら取得する
GetDirectoriesフォルダ一覧を配列として取得する
EnumerateDirectoriesフォルダを列挙しながら取得する
GetCurrentDirectory現在の作業フォルダを取得する
SetCurrentDirectory現在の作業フォルダを変更する

例えば、空のフォルダを削除する場合はDirectory.Deleteを使用します。

C#
string folderPath = @"C:\Sample";

if (Directory.Exists(folderPath))
{
Directory.Delete(folderPath);
}

フォルダ内のファイルやサブフォルダも含めて削除する場合は、第2引数にtrueを指定します。

C#
Directory.Delete(folderPath, true);

この処理ではフォルダ内のデータがすべて削除されます。実行前に対象パスが正しいか十分に確認してください。

1-2. DirectoryInfoクラスとの違い

C#には、Directoryと似た機能を持つDirectoryInfoクラスもあります。

両者の主な違いは、静的クラスかインスタンスクラスかという点です。

C#
// Directoryを使用する場合
Directory.CreateDirectory(@"C:\Sample");

// DirectoryInfoを使用する場合
DirectoryInfo directoryInfo = new DirectoryInfo(@"C:\Sample");
directoryInfo.Create();

Directoryは、フォルダに対して1回だけ処理を行う場合に適しています。一方、DirectoryInfoは同じフォルダの情報を繰り返し参照するときに便利です。

C#
DirectoryInfo directoryInfo = new DirectoryInfo(@"C:\Sample");

Console.WriteLine(directoryInfo.FullName);
Console.WriteLine(directoryInfo.Name);
Console.WriteLine(directoryInfo.CreationTime);
Console.WriteLine(directoryInfo.LastWriteTime);

単純な作成、存在確認、削除、一覧取得であればDirectory、特定のフォルダに関する情報をまとめて扱う場合はDirectoryInfoと使い分けるとよいでしょう。

1-3. System.IO名前空間を読み込む方法

Directoryクラスを使用するには、ソースコードの先頭でSystem.IO名前空間を読み込みます。

C#
using System.IO;

これにより、次のようにDirectoryと記述できます。

C#
Directory.CreateDirectory(@"C:\Sample");

using System.IO;を記述しない場合は、完全修飾名を使用します。

C#
System.IO.Directory.CreateDirectory(@"C:\Sample");

ファイルやフォルダを扱うコードでは、Directory以外にもFileFileInfoPathなどを利用することが多いため、基本的にはusing System.IO;を追加しておくと便利です。

1-4. フォルダ操作で使用するパスの基本

C#でフォルダを操作する際は、絶対パスまたは相対パスを指定します。

絶対パスは、ドライブ名やルートから始まる完全なパスです。

C#
string folderPath = @"C:\Work\Data";

相対パスは、アプリケーションの現在の作業フォルダを基準にしたパスです。

C#
string folderPath = @"Data\Images";

Windowsのパスにはバックスラッシュが含まれます。通常の文字列ではバックスラッシュがエスケープ文字として扱われるため、次のように2つ重ねる必要があります。

C#
string folderPath = "C:\\Work\\Data";

文字列の先頭に@を付けた逐語的文字列リテラルを使用すれば、バックスラッシュをそのまま記述できます。

C#
string folderPath = @"C:\Work\Data";

複数のパスを連結するときは、文字列を直接結合するのではなくPath.Combineを使用するのが安全です。

C#
string basePath = @"C:\Work";
string folderPath = Path.Combine(basePath, "Data", "Images");

Console.WriteLine(folderPath);

Path.Combineを使用すると、環境に応じた区切り文字を考慮してパスを組み立てられます。

2. C#のDirectoryでフォルダを作成する方法

C#でフォルダを作成する場合は、Directory.CreateDirectoryメソッドを使用します。

2-1. Directory.CreateDirectoryの基本的な使い方

Directory.CreateDirectoryの引数に、作成したいフォルダのパスを指定します。

C#
using System;
using System.IO;

string folderPath = @"C:\Work\Sample";

Directory.CreateDirectory(folderPath);

Console.WriteLine("フォルダを作成しました。");

CreateDirectoryの戻り値は、作成したフォルダを表すDirectoryInfoオブジェクトです。

C#
DirectoryInfo directoryInfo =
Directory.CreateDirectory(@"C:\Work\Sample");

Console.WriteLine(directoryInfo.FullName);

作成したフォルダの名前、作成日時、更新日時などを続けて参照したい場合に利用できます。

なお、指定した場所にフォルダを作成する権限がない場合や、パスが不正な場合は例外が発生する可能性があります。

C#
try
{
Directory.CreateDirectory(@"C:\Work\Sample");
Console.WriteLine("フォルダを作成しました。");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("フォルダを作成する権限がありません。");
}
catch (IOException ex)
{
Console.WriteLine($"入出力エラーが発生しました: {ex.Message}");
}

2-2. 階層が深いフォルダを一括で作成する方法

Directory.CreateDirectoryは、途中のフォルダが存在しない場合でも、必要な階層をまとめて作成します。

C#
string folderPath = @"C:\Work\Project\Data\Images";

Directory.CreateDirectory(folderPath);

例えば、C:\Work\Projectまでしか存在していなくても、DataImagesが自動的に作成されます。

Path.Combineを利用して組み立てることもできます。

C#
string basePath = @"C:\Work";
string folderPath = Path.Combine(
basePath,
"Project",
"Data",
"Images"
);

Directory.CreateDirectory(folderPath);

階層ごとにCreateDirectoryを繰り返す必要はありません。

2-3. 同名フォルダがすでに存在する場合の動作

Directory.CreateDirectoryで指定したフォルダがすでに存在していても、通常は例外になりません。

C#
string folderPath = @"C:\Work\Sample";

Directory.CreateDirectory(folderPath);
Directory.CreateDirectory(folderPath);

同じ処理を複数回実行しても、既存のフォルダはそのまま利用されます。フォルダ内に保存されているファイルが削除されたり、フォルダが初期化されたりすることもありません。

そのため、単にフォルダがなければ作成したい場合は、存在確認を省略して次のように記述できます。

C#
Directory.CreateDirectory(folderPath);

ただし、作成時と既存時で処理を分けたい場合は、Directory.Existsと組み合わせます。

C#
if (Directory.Exists(folderPath))
{
Console.WriteLine("フォルダはすでに存在します。");
}
else
{
Directory.CreateDirectory(folderPath);
Console.WriteLine("フォルダを新規作成しました。");
}

2-4. 相対パスと絶対パスを指定する方法

絶対パスを使用すると、実行環境にかかわらず明示した場所にフォルダが作成されます。

C#
string absolutePath = @"C:\Work\Sample";

Directory.CreateDirectory(absolutePath);

相対パスを使用した場合は、現在の作業フォルダを基準に作成されます。

C#
string relativePath = Path.Combine("Data", "Images");

Directory.CreateDirectory(relativePath);

現在の作業フォルダは、Directory.GetCurrentDirectoryで確認できます。

C#
string currentDirectory = Directory.GetCurrentDirectory();

Console.WriteLine(currentDirectory);

相対パスを絶対パスに変換したい場合は、Path.GetFullPathを使用します。

C#
string relativePath = Path.Combine("Data", "Images");
string absolutePath = Path.GetFullPath(relativePath);

Console.WriteLine(absolutePath);

アプリケーションの実行ファイルが置かれているフォルダを基準にしたい場合は、AppContext.BaseDirectoryを使用できます。

C#
string folderPath = Path.Combine(
AppContext.BaseDirectory,
"Data",
"Images"
);

Directory.CreateDirectory(folderPath);

現在の作業フォルダと実行ファイルの配置場所は、必ずしも同じではありません。保存場所を固定したい場合は、どのフォルダを基準にするか明確にしておくことが重要です。

3. C#のDirectoryでフォルダの存在を確認する方法

フォルダが存在するか確認する場合は、Directory.Existsメソッドを使用します。

3-1. Directory.Existsの基本的な使い方

Directory.Existsは、指定したフォルダが存在する場合にtrue、存在しない場合にfalseを返します。

C#
string folderPath = @"C:\Work\Sample";

bool exists = Directory.Exists(folderPath);

Console.WriteLine(exists);

一般的には、if文と組み合わせて使用します。

C#
if (Directory.Exists(folderPath))
{
Console.WriteLine("フォルダが存在します。");
}
else
{
Console.WriteLine("フォルダが存在しません。");
}

Directory.Existsは、存在確認に失敗した場合も例外ではなくfalseを返すことがあります。そのため、falseが返されたからといって、必ずしもフォルダが物理的に存在しないとは限りません。

3-2. フォルダが存在する場合だけ処理を実行する方法

対象フォルダが存在する場合だけファイルを取得したいときは、次のように記述します。

C#
string folderPath = @"C:\Work\Sample";

if (Directory.Exists(folderPath))
{
string[] files = Directory.GetFiles(folderPath);

foreach (string file in files)
{
Console.WriteLine(file);
}
}

存在しないフォルダに対してDirectory.GetFilesを実行すると、DirectoryNotFoundExceptionが発生する可能性があります。

フォルダ削除を行う場合も、存在確認と組み合わせられます。

C#
if (Directory.Exists(folderPath))
{
Directory.Delete(folderPath, true);
Console.WriteLine("フォルダを削除しました。");
}

ただし、存在確認の直後に別の処理によってフォルダが削除される可能性もあります。重要な処理では、存在確認だけに頼らず例外処理も実装しましょう。

3-3. フォルダが存在しない場合に新規作成する方法

フォルダが存在しない場合だけ新規作成するコードは、次のとおりです。

C#
string folderPath = @"C:\Work\Sample";

if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
Console.WriteLine("フォルダを作成しました。");
}

!は真偽値を反転する演算子です。Directory.Existsfalseの場合に、ifブロック内の処理が実行されます。

ただし、Directory.CreateDirectoryは同名フォルダが存在していても通常は問題なく実行できます。作成されたかどうかを区別する必要がなければ、次の1行でも十分です。

C#
Directory.CreateDirectory(folderPath);

存在確認と作成の間に別の処理が割り込む可能性を考慮すると、単純にCreateDirectoryを実行する方法のほうが扱いやすい場合もあります。

3-4. Directory.Existsがfalseになる主な原因

Directory.Existsfalseを返す主な原因は、次のとおりです。

  • 指定したフォルダが存在しない

  • パスのスペルが間違っている

  • 相対パスの基準となる作業フォルダが想定と異なる

  • フォルダではなくファイルのパスを指定している

  • ネットワークドライブや共有フォルダに接続できない

  • 対象フォルダへアクセスする権限がない

  • パスに使用できない文字が含まれている

  • 指定したドライブや外部ストレージが利用できない

相対パスが原因か確認するには、Path.GetFullPathで実際の参照先を表示すると便利です。

C#
string folderPath = Path.Combine("Data", "Images");

Console.WriteLine(Path.GetFullPath(folderPath));
Console.WriteLine(Directory.Exists(folderPath));

ファイルのパスを誤って指定していないか確認したい場合は、File.Existsも利用できます。

C#
string path = @"C:\Work\Sample\data.txt";

Console.WriteLine($"フォルダ: {Directory.Exists(path)}");
Console.WriteLine($"ファイル: {File.Exists(path)}");

ネットワーク上のフォルダを扱う場合は、一時的な通信障害や認証状態によって結果が変わる可能性も考慮しましょう。

4. C#のDirectoryでファイルを取得する方法

Directoryクラスを使用すると、指定したフォルダに保存されているファイルを取得できます。

すべてのファイルを一括取得する方法だけでなく、拡張子やサブフォルダ、更新日時などを条件に絞り込むことも可能です。

4-1. Directory.GetFilesでファイル一覧を取得する方法

Directory.GetFilesの第1引数にフォルダのパスを指定すると、そのフォルダ直下にあるファイルのパスが配列で返されます。

C#
string folderPath = @"C:\Work\Sample";

string[] files = Directory.GetFiles(folderPath);

foreach (string file in files)
{
Console.WriteLine(file);
}

戻り値はstring[]で、それぞれの要素にはファイル名だけでなくパスが格納されます。

フォルダが存在しない場合は例外が発生するため、必要に応じて存在確認を行います。

C#
if (!Directory.Exists(folderPath))
{
Console.WriteLine("対象フォルダが存在しません。");
return;
}

string[] files = Directory.GetFiles(folderPath);

ファイルの取得中には、アクセス権限やファイルシステムの状態によって例外が発生することもあります。

C#
try
{
string[] files = Directory.GetFiles(folderPath);

foreach (string file in files)
{
Console.WriteLine(file);
}
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("フォルダへアクセスする権限がありません。");
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("対象フォルダが見つかりません。");
}
catch (IOException ex)
{
Console.WriteLine($"入出力エラーが発生しました: {ex.Message}");
}

4-2. 拡張子を指定してファイルを検索する方法

Directory.GetFilesの第2引数には、検索パターンを指定できます。

例えば、拡張子が.txtのファイルだけを取得する場合は次のように記述します。

C#
string folderPath = @"C:\Work\Sample";

string[] textFiles = Directory.GetFiles(
folderPath,
"*.txt"
);

foreach (string file in textFiles)
{
Console.WriteLine(file);
}

画像ファイルのうち.pngだけを取得する場合は、次のとおりです。

C#
string[] pngFiles = Directory.GetFiles(
folderPath,
"*.png"
);

ファイル名の先頭部分を条件にすることもできます。

C#
string[] logFiles = Directory.GetFiles(
folderPath,
"log_*.txt"
);

この例では、log_20260620.txtlog_error.txtなどが検索対象になります。

複数の拡張子を対象にしたい場合は、すべてのファイルを列挙したうえでLINQを使用すると柔軟に絞り込めます。

C#
using System;
using System.IO;
using System.Linq;

string[] targetExtensions = { ".jpg", ".jpeg", ".png" };

var imageFiles = Directory
.EnumerateFiles(folderPath)
.Where(file =>
targetExtensions.Contains(
Path.GetExtension(file),
StringComparer.OrdinalIgnoreCase
)
);

foreach (string file in imageFiles)
{
Console.WriteLine(file);
}

StringComparer.OrdinalIgnoreCaseを指定することで、.png.PNGのような大文字・小文字の違いを無視できます。

4-3. SearchOptionでサブフォルダ内のファイルも取得する方法

Directory.GetFilesの第3引数にSearchOptionを指定すると、サブフォルダを検索対象にするか制御できます。

指定できる主な値は次の2つです。

検索範囲
SearchOption.TopDirectoryOnly指定したフォルダ直下のみ
SearchOption.AllDirectoriesすべてのサブフォルダを含む

サブフォルダ内も含めてテキストファイルを取得するコードは、次のとおりです。

C#
string[] files = Directory.GetFiles(
@"C:\Work\Sample",
"*.txt",
SearchOption.AllDirectories
);

foreach (string file in files)
{
Console.WriteLine(file);
}

指定したフォルダ直下だけを検索する場合は、次のように記述します。

C#
string[] files = Directory.GetFiles(
@"C:\Work\Sample",
"*.txt",
SearchOption.TopDirectoryOnly
);

第3引数を省略した場合は、基本的にTopDirectoryOnlyと同じく、指定フォルダ直下だけが対象です。

AllDirectoriesは手軽ですが、アクセス権限のないサブフォルダが含まれていると例外が発生する場合があります。また、フォルダ数が多い環境では処理に時間がかかることにも注意が必要です。

4-4. Directory.EnumerateFilesとの違いと使い分け

Directory.GetFilesは、条件に一致するファイルをすべて取得してから配列として返します。

C#
string[] files = Directory.GetFiles(folderPath);

一方、Directory.EnumerateFilesは、ファイルを必要なタイミングで順番に列挙します。

C#
IEnumerable<string> files =
Directory.EnumerateFiles(folderPath);

GetFilesはすべての結果がそろってから後続処理を開始しますが、EnumerateFilesは最初のファイルが見つかった段階から処理を始められます。

C#
foreach (string file in Directory.EnumerateFiles(folderPath))
{
Console.WriteLine(file);
}

大量のファイルを扱う場合は、すべてのパスを一度にメモリへ保持しないEnumerateFilesが適しています。

また、途中で検索を終了できる点もメリットです。

C#
string? firstTextFile = Directory
.EnumerateFiles(
folderPath,
"*.txt",
SearchOption.AllDirectories
)
.FirstOrDefault();

if (firstTextFile is not null)
{
Console.WriteLine(firstTextFile);
}

使い分けの目安は次のとおりです。

  • 結果を配列として何度も使用する場合はGetFiles

  • ファイル数が少ない場合はGetFiles

  • 大量のファイルを順番に処理する場合はEnumerateFiles

  • 条件に一致する最初のファイルだけ必要な場合はEnumerateFiles

ただし、EnumerateFilesでも、実際に列挙を開始した時点でアクセス権限などの例外が発生する可能性があります。

4-5. ファイル名だけを取り出す方法

Directory.GetFilesDirectory.EnumerateFilesで取得できるのは、基本的にファイルのパスです。

ファイル名だけを取り出したい場合は、Path.GetFileNameを使用します。

C#
string[] files = Directory.GetFiles(folderPath);

foreach (string file in files)
{
string fileName = Path.GetFileName(file);
Console.WriteLine(fileName);
}

例えば、取得したパスが次の場合を考えます。

C:\Work\Sample\document.txt

Path.GetFileNameの結果は次のようになります。

document.txt

拡張子を除いたファイル名だけを取得する場合は、Path.GetFileNameWithoutExtensionを使用します。

C#
foreach (string file in files)
{
string fileName =
Path.GetFileNameWithoutExtension(file);

Console.WriteLine(fileName);
}

この場合、document.txtからdocumentだけを取得できます。

LINQを使用して、ファイル名の一覧を作ることも可能です。

C#
string[] fileNames = Directory
.GetFiles(folderPath)
.Select(Path.GetFileName)
.ToArray();

foreach (string fileName in fileNames)
{
Console.WriteLine(fileName);
}

4-6. 更新日時やファイルサイズを条件に絞り込む方法

更新日時やファイルサイズを条件にする場合は、取得したパスからFileInfoオブジェクトを作成します。

次の例では、過去7日以内に更新されたファイルを取得しています。

C#
using System;
using System.IO;
using System.Linq;

string folderPath = @"C:\Work\Sample";
DateTime threshold = DateTime.Now.AddDays(-7);

var recentFiles = Directory
.EnumerateFiles(
folderPath,
"*",
SearchOption.AllDirectories
)
.Select(file => new FileInfo(file))
.Where(file => file.LastWriteTime >= threshold);

foreach (FileInfo file in recentFiles)
{
Console.WriteLine(
$"{file.FullName} / {file.LastWriteTime}"
);
}

ファイルサイズが1MB以上のものだけを取得する場合は、FileInfo.Lengthを使用します。

C#
long minimumSize = 1024L * 1024L;

var largeFiles = Directory
.EnumerateFiles(folderPath)
.Select(file => new FileInfo(file))
.Where(file => file.Length >= minimumSize);

foreach (FileInfo file in largeFiles)
{
Console.WriteLine(
$"{file.Name} / {file.Length} bytes"
);
}

更新日時とファイルサイズを組み合わせることもできます。

C#
DateTime threshold = DateTime.Now.AddDays(-30);
long minimumSize = 5L * 1024L * 1024L;

var targetFiles = Directory
.EnumerateFiles(
folderPath,
"*",
SearchOption.AllDirectories
)
.Select(file => new FileInfo(file))
.Where(file =>
file.LastWriteTime >= threshold &&
file.Length >= minimumSize
)
.OrderByDescending(file => file.LastWriteTime);

foreach (FileInfo file in targetFiles)
{
Console.WriteLine(
$"{file.Name} / " +
$"{file.Length:N0} bytes / " +
$"{file.LastWriteTime}"
);
}

FileInfo.Lengthの単位はバイトです。KBやMBを条件にするときは、1024を基準に換算します。

5. C#のDirectoryでフォルダ一覧を取得する方法

Directoryクラスでは、ファイルだけでなくフォルダの一覧も取得できます。

5-1. Directory.GetDirectoriesの基本的な使い方

Directory.GetDirectoriesに対象フォルダのパスを指定すると、直下にあるフォルダのパスが配列として返されます。

C#
string folderPath = @"C:\Work";

string[] directories =
Directory.GetDirectories(folderPath);

foreach (string directory in directories)
{
Console.WriteLine(directory);
}

フォルダ名だけを表示したい場合は、Path.GetFileNameを使用します。

C#
foreach (string directory in directories)
{
Console.WriteLine(Path.GetFileName(directory));
}

対象フォルダが存在しない場合やアクセス権限がない場合には、例外が発生する可能性があります。

C#
if (Directory.Exists(folderPath))
{
string[] directories =
Directory.GetDirectories(folderPath);

foreach (string directory in directories)
{
Console.WriteLine(directory);
}
}

5-2. 条件に一致するフォルダだけを検索する方法

Directory.GetDirectoriesの第2引数に検索パターンを指定すると、条件に一致するフォルダだけを取得できます。

例えば、名前がDataから始まるフォルダを取得する場合は、次のように記述します。

C#
string[] directories = Directory.GetDirectories(
@"C:\Work",
"Data*"
);

foreach (string directory in directories)
{
Console.WriteLine(directory);
}

この検索では、DataData01DataBackupなどが対象になります。

より複雑な条件で絞り込みたい場合は、LINQを使用します。

C#
var directories = Directory
.EnumerateDirectories(@"C:\Work")
.Where(directory =>
Path.GetFileName(directory)
.Contains(
"backup",
StringComparison.OrdinalIgnoreCase
)
);

foreach (string directory in directories)
{
Console.WriteLine(directory);
}

この例では、フォルダ名にbackupが含まれているフォルダを、大文字・小文字を区別せず取得します。

5-3. サブフォルダを再帰的に取得する方法

すべての階層からフォルダを取得する場合は、第3引数にSearchOption.AllDirectoriesを指定します。

C#
string[] directories = Directory.GetDirectories(
@"C:\Work",
"*",
SearchOption.AllDirectories
);

foreach (string directory in directories)
{
Console.WriteLine(directory);
}

第2引数の"*"は、すべてのフォルダ名を検索対象にする指定です。

特定の名前から始まるフォルダだけを、すべての階層から検索することもできます。

C#
string[] directories = Directory.GetDirectories(
@"C:\Work",
"Data*",
SearchOption.AllDirectories
);

再帰検索では、アクセスできないサブフォルダや非常に深い階層が含まれる場合があります。単純なAllDirectoriesで例外が問題になる場合は、フォルダごとに例外処理を行いながら再帰的に探索する方法もあります。

C#
using System;
using System.Collections.Generic;
using System.IO;

static IEnumerable<string> EnumerateDirectoriesSafely(
string rootPath)
{
string[] childDirectories;

try
{
childDirectories =
Directory.GetDirectories(rootPath);
}
catch (UnauthorizedAccessException)
{
yield break;
}
catch (IOException)
{
yield break;
}

foreach (string childDirectory in childDirectories)
{
yield return childDirectory;

foreach (string descendant in
EnumerateDirectoriesSafely(childDirectory))
{
yield return descendant;
}
}
}

呼び出し側では、次のように使用します。

C#
foreach (string directory in
EnumerateDirectoriesSafely(@"C:\Work"))
{
Console.WriteLine(directory);
}

この方法では、アクセスできないフォルダをスキップしながら、ほかのフォルダの探索を継続できます。

5-4. Directory.EnumerateDirectoriesとの違い

Directory.GetDirectoriesは、条件に一致するすべてのフォルダを取得してから配列として返します。

C#
string[] directories =
Directory.GetDirectories(@"C:\Work");

Directory.EnumerateDirectoriesは、フォルダを順番に列挙します。

C#
IEnumerable<string> directories =
Directory.EnumerateDirectories(@"C:\Work");

結果を順番に処理するだけであれば、次のように直接foreach文で使用できます。

C#
foreach (string directory in
Directory.EnumerateDirectories(@"C:\Work"))
{
Console.WriteLine(directory);
}

大量のフォルダが存在する場合は、すべてのパスを一度に配列へ格納しないEnumerateDirectoriesが適しています。

条件に一致する最初のフォルダだけを取得することもできます。

C#
string? firstDirectory = Directory
.EnumerateDirectories(
@"C:\Work",
"Data*",
SearchOption.AllDirectories
)
.FirstOrDefault();

if (firstDirectory is not null)
{
Console.WriteLine(firstDirectory);
}

使い分けの目安は、ファイル取得時と同様です。

  • フォルダ一覧を配列として保持したい場合はGetDirectories

  • フォルダ数が少ない場合はGetDirectories

  • 大量のフォルダを順番に処理する場合はEnumerateDirectories

  • 必要なフォルダが見つかった時点で終了したい場合はEnumerateDirectories

まとめ

C#のDirectoryクラスを使用すると、フォルダの作成、存在確認、削除、ファイル取得、フォルダ一覧の取得といった処理を簡潔に実装できます。

フォルダを作成するときはDirectory.CreateDirectory、存在を確認するときはDirectory.Exists、削除するときはDirectory.Deleteを使用します。ファイル一覧にはGetFilesまたはEnumerateFiles、フォルダ一覧にはGetDirectoriesまたはEnumerateDirectoriesを使用します。

少量の結果を配列として扱いたい場合はGetFilesGetDirectoriesが分かりやすく、大量のデータを順番に処理する場合はEnumerateFilesEnumerateDirectoriesが適しています。

また、実際のアプリケーションでは、存在しないパス、アクセス権限の不足、ネットワーク障害などによって例外が発生する可能性があります。Path.Combineによる安全なパス生成や、try-catchによる例外処理も組み合わせ、実行環境に左右されにくいフォルダ操作を実装しましょう。