C# Directory.GetDirectoriesの使い方|指定フォルダ内のディレクトリ一覧を取得する方法

はじめに

C#で指定フォルダ内のディレクトリ一覧を取得したい場合は、Directory.GetDirectoriesを使うのが基本です。

たとえば、あるフォルダの直下にあるサブフォルダを一覧表示したい、特定の名前を含むフォルダだけ取得したい、サブディレクトリを含めてすべてのフォルダを取得したい、といった場面で利用できます。

c# directory.getdirectoriesで調べている方の多くは、「指定したパス配下のフォルダ一覧をどう取得するのか」「ファイルではなくフォルダだけを取得するにはどうするのか」「再帰的に取得するにはどう書くのか」を知りたいはずです。

この記事では、Directory.GetDirectoriesの基本構文から、検索パターン、再帰検索、例外処理、Directory.EnumerateDirectoriesDirectoryInfo.GetDirectoriesとの違いまで、実用的なサンプルコード付きで解説します。

1. C#のDirectory.GetDirectoriesとは

Directory.GetDirectoriesは、指定したディレクトリ内にあるサブディレクトリのパスを取得するためのメソッドです。

System.IO.Directoryクラスに用意されている静的メソッドで、戻り値は基本的にstring[]です。取得できるのは「ファイル」ではなく「ディレクトリ」です。

Microsoft Learnでも、Directory.GetDirectoriesは指定したディレクトリ内のサブディレクトリ名を、パスを含む文字列配列として返すメソッドとして説明されています。

1-1. Directory.GetDirectoriesでできること

Directory.GetDirectoriesを使うと、主に次のような処理ができます。

指定フォルダ直下のサブフォルダ一覧を取得できます。

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

指定した名前に一致するフォルダだけを取得できます。

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

サブフォルダのさらに下にあるフォルダまで再帰的に取得できます。

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

このように、Directory.GetDirectoriesは「フォルダ一覧を取得する」処理でよく使われます。

1-2. 指定フォルダ内のディレクトリ一覧を取得する基本用途

もっとも基本的な用途は、指定したフォルダの直下にあるディレクトリを取得することです。

たとえば、C:\Workの中に次のようなフォルダがあるとします。

C:\Work
├─ ProjectA
├─ ProjectB
└─ Backup

このとき、次のコードを実行すると、ProjectAProjectBBackupのパスを取得できます。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = @"C:\Work";

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

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

実行結果の例は次のようになります。

C:\Work\ProjectA
C:\Work\ProjectB
C:\Work\Backup

Directory.GetDirectoriesは、フォルダ名だけではなく、パスを含む文字列を返す点に注意しましょう。

1-3. GetDirectoriesとGetFilesの違い

GetDirectoriesとよく似たメソッドにGetFilesがあります。

Directory.GetDirectoriesはディレクトリを取得します。一方、Directory.GetFilesはファイルを取得します。

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

たとえば、次のような構成があるとします。

C:\Work
├─ ProjectA
├─ ProjectB
├─ memo.txt
└─ report.xlsx

GetDirectoriesで取得できるのはProjectAProjectBなどのフォルダです。memo.txtreport.xlsxなどのファイルは取得されません。

逆に、GetFilesで取得できるのはファイルであり、フォルダは取得されません。

フォルダ一覧を取得したい場合はGetDirectories、ファイル一覧を取得したい場合はGetFilesを使います。

1-4. Directoryクラスを使うために必要なusing

Directory.GetDirectoriesを使うには、通常はファイルの先頭に次のusingを記述します。

C#
using System.IO;

DirectoryクラスはSystem.IO名前空間に含まれています。

using System.IO;を書かない場合は、次のように完全修飾名で呼び出すこともできます。

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

ただし、コードを読みやすくするため、多くの場合はusing System.IO;を追加しておくのがおすすめです。

2. Directory.GetDirectoriesの基本的な使い方

ここからは、Directory.GetDirectoriesの基本的な使い方を見ていきます。

まずは、最もシンプルな構文から確認しましょう。

2-1. 最もシンプルな構文

Directory.GetDirectoriesの最もシンプルな構文は次のとおりです。

C#
Directory.GetDirectories(string path)

使用例は次のようになります。

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

pathには、ディレクトリ一覧を取得したいフォルダのパスを指定します。

戻り値はstring[]です。つまり、ディレクトリパスの配列が返ってきます。

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

指定したフォルダ内にサブディレクトリがない場合は、空の配列が返されます。条件に一致するディレクトリがない場合も同様です。

2-2. 指定したパス直下のフォルダ一覧を取得するサンプルコード

次のサンプルでは、指定したパス直下のフォルダ一覧を取得して表示します。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string targetPath = @"C:\Work";

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

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

Directory.GetDirectories(targetPath)によって、targetPath直下にあるフォルダ一覧を取得しています。

たとえば、C:\Work配下にAppDataLogsというフォルダがある場合、次のような結果になります。

C:\Work\App
C:\Work\Data
C:\Work\Logs

2-3. 戻り値の型と取得できるパスの形式

Directory.GetDirectoriesの戻り値はstring[]です。

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

配列の各要素には、取得したディレクトリのパスが文字列として格納されます。

通常、指定したパスに応じた形式で返されます。

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

絶対パスを指定した場合は、絶対パス形式で扱いやすくなります。

C:\Work\App
C:\Work\Data

相対パスを指定した場合は、現在の作業ディレクトリからの相対パスとして解釈されます。Directory.GetDirectoriespathには相対パスまたは絶対パスを指定できます。

実務では、パスの解釈ミスを避けるため、可能であれば絶対パスを指定する方が安全です。

2-4. foreachでディレクトリ一覧を表示する方法

取得したディレクトリ一覧は、foreachで1件ずつ処理できます。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string[] directories = Directory.GetDirectories(@"C:\Work");

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

Directory.GetDirectoriesの戻り値は配列なので、foreachとの相性がよいです。

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

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

このように、まずGetDirectoriesで一覧を取得し、foreachで1件ずつ処理するのが基本パターンです。

3. 検索パターンを指定してディレクトリを取得する方法

Directory.GetDirectoriesでは、検索パターンを指定してディレクトリを絞り込むこともできます。

たとえば、「名前がProjectで始まるフォルダだけ取得する」「Logを含むフォルダだけ取得する」といった処理が可能です。

3-1. searchPattern引数の使い方

検索パターンを指定する場合は、次の構文を使います。

C#
Directory.GetDirectories(string path, string searchPattern)

使用例は次のとおりです。

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

このコードでは、C:\Work直下にあるフォルダのうち、名前がProjectで始まるディレクトリだけを取得します。

たとえば、次のようなフォルダ構成があるとします。

C:\Work
├─ ProjectA
├─ ProjectB
├─ TestProject
└─ Backup

"Project*"を指定した場合、取得されるのは次のフォルダです。

C:\Work\ProjectA
C:\Work\ProjectB

TestProjectProjectで始まっていないため、この例では対象外です。

3-2. 特定の名前を含むフォルダだけ取得する

特定の文字列を含むフォルダを取得したい場合は、前後に*を付けます。

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

このコードでは、名前にProjectを含むフォルダを取得します。

たとえば、次のようなフォルダがある場合、

ProjectA
TestProject
OldProjectBackup
Data

"*Project*"に一致するのは次のフォルダです。

ProjectA
TestProject
OldProjectBackup

検索パターンには、リテラル文字とワイルドカード文字を組み合わせて指定できます。ただし、正規表現ではありません。

3-3. ワイルドカードを使った絞り込み例

Directory.GetDirectoriessearchPatternでは、主に*?のワイルドカードを使います。

*は0文字以上の任意の文字に一致します。

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

この場合、次のようなフォルダに一致します。

Log
Logs
Log_2026

?は任意の1文字に一致します。

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

この場合、次のようなフォルダに一致します。

Data1
DataA
Data_

一方で、次のようなフォルダには一致しません。

Data
Data10

*?の意味はMicrosoft Learnでも説明されており、*は0個以上の文字、?は1文字に一致します。

3-4. searchPattern使用時の注意点

searchPatternを使うときは、次の点に注意しましょう。

まず、searchPatternは正規表現ではありません。

C#
// 正規表現のつもりで書いても期待通りには動かない
string[] directories = Directory.GetDirectories(@"C:\Work", "^Project[0-9]+$");

このような正規表現風の指定は、Directory.GetDirectoriesの検索パターンとしては使えません。

また、条件に一致するディレクトリがない場合は、例外ではなく空の配列が返ります。

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

Console.WriteLine(directories.Length); // 0

さらに、searchPatternnullを指定すると例外の原因になります。パターンが不要な場合は、"*"を指定するか、Directory.GetDirectories(path)を使いましょう。

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

4. サブディレクトリまで再帰的に取得する方法

Directory.GetDirectoriesでは、指定フォルダ直下だけでなく、サブディレクトリのさらに下まで再帰的に取得できます。

再帰検索を行う場合は、SearchOptionを指定します。

4-1. SearchOption.TopDirectoryOnlyとAllDirectoriesの違い

SearchOptionには、主に次の2種類があります。

C#
SearchOption.TopDirectoryOnly
SearchOption.AllDirectories

TopDirectoryOnlyは、指定したフォルダの直下だけを検索します。

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

AllDirectoriesは、指定したフォルダ配下のすべてのサブディレクトリを再帰的に検索します。

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

Directory.GetDirectoriesSearchOption引数は、すべてのサブディレクトリを含めるか、現在のディレクトリのみを含めるかを指定するために使います。

4-2. 配下すべてのディレクトリを取得するサンプルコード

次のコードでは、指定フォルダ配下のすべてのディレクトリを取得します。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string targetPath = @"C:\Work";

string[] directories = Directory.GetDirectories(
targetPath,
"*",
SearchOption.AllDirectories
);

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

たとえば、次のようなフォルダ構成があるとします。

C:\Work
├─ App
│ ├─ Controllers
│ └─ Models
└─ Logs
└─ Archive

SearchOption.AllDirectoriesを指定すると、次のように深い階層のフォルダも取得できます。

C:\Work\App
C:\Work\App\Controllers
C:\Work\App\Models
C:\Work\Logs
C:\Work\Logs\Archive

4-3. 再帰検索で階層構造を取得する方法

Directory.GetDirectoriesで取得した結果は、単純なパスの配列です。

そのため、階層構造らしく表示したい場合は、パスの深さを計算してインデントを付ける方法があります。

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

class Program
{
static void Main()
{
string rootPath = @"C:\Work";

string[] directories = Directory.GetDirectories(
rootPath,
"*",
SearchOption.AllDirectories
);

foreach (string directory in directories)
{
int depth = directory
.Substring(rootPath.Length)
.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)
.Length;

string indent = new string(' ', depth * 2);
Console.WriteLine($"{indent}{Path.GetFileName(directory)}");
}
}
}

実行結果の例は次のようになります。

  App
Controllers
Models
Logs
Archive

このように、GetDirectoriesの結果を加工することで、ツリー表示のような形にすることもできます。

4-4. 大量のフォルダを取得するときの注意点

SearchOption.AllDirectoriesは便利ですが、対象フォルダ配下に大量のディレクトリがある場合は注意が必要です。

Directory.GetDirectoriesは、条件に一致するディレクトリを配列として一括取得します。そのため、件数が多い場合は処理開始まで時間がかかったり、メモリ使用量が増えたりする可能性があります。

大量のディレクトリを扱う場合は、後述するDirectory.EnumerateDirectoriesの利用も検討しましょう。EnumerateDirectoriesは全体が返る前に列挙を開始できるため、多数のファイルやディレクトリを扱う場合に効率的です。

5. Directory.GetDirectoriesの主なオーバーロード

Directory.GetDirectoriesには、用途に応じて複数のオーバーロードがあります。

主なオーバーロードは次の4つです。

C#
Directory.GetDirectories(string path)

Directory.GetDirectories(string path, string searchPattern)

Directory.GetDirectories(string path, string searchPattern, SearchOption searchOption)

Directory.GetDirectories(string path, string searchPattern, EnumerationOptions enumerationOptions)

Microsoft Learnでも、これらのオーバーロードが用意されていることが確認できます。

5-1. GetDirectories(string path)

最も基本的な形式です。

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

指定したフォルダの直下にあるサブディレクトリを取得します。

検索パターンや再帰検索を指定しない場合は、この形式で十分です。

5-2. GetDirectories(string path, string searchPattern)

検索パターンを指定する形式です。

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

この例では、C:\Work直下にあるフォルダのうち、名前がProjectで始まるフォルダだけを取得します。

フォルダ名で絞り込みたい場合に使います。

5-3. GetDirectories(string path, string searchPattern, SearchOption searchOption)

検索パターンと検索範囲を指定する形式です。

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

この例では、C:\Work配下のすべての階層から、名前がProjectで始まるフォルダを取得します。

直下のみ検索したい場合は、SearchOption.TopDirectoryOnlyを指定します。

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

5-4. GetDirectories(string path, string searchPattern, EnumerationOptions enumerationOptions)

より細かい列挙オプションを指定したい場合は、EnumerationOptionsを使います。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
var options = new EnumerationOptions
{
RecurseSubdirectories = true,
IgnoreInaccessible = true
};

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

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

EnumerationOptionsでは、サブディレクトリを再帰的に検索するか、アクセスできないファイルやディレクトリをスキップするか、最大再帰深度をどうするかなどを指定できます。

アクセス権限のないフォルダを含む可能性がある場合は、IgnoreInaccessible = trueが役立つことがあります。

C#
var options = new EnumerationOptions
{
RecurseSubdirectories = true,
IgnoreInaccessible = true
};

ただし、環境や対象パスによっては例外処理も必要になるため、実務ではtry-catchと組み合わせると安全です。

6. 実用的なサンプルコード

ここでは、Directory.GetDirectoriesを実務で使うときによくあるサンプルを紹介します。

フォルダ名だけ取得する方法、LINQで絞り込む方法、Listに変換する方法、更新日時で並び替える方法を確認しましょう。

6-1. 指定フォルダ内のフォルダ名だけを取得する

Directory.GetDirectoriesはパスを含む文字列を返します。

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

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string targetPath = @"C:\Work";

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

foreach (string directory in directories)
{
string folderName = Path.GetFileName(directory);
Console.WriteLine(folderName);
}
}
}

実行結果の例です。

ProjectA
ProjectB
Backup

フルパスではなく表示用の名前だけが必要な場合に便利です。

6-2. フルパスではなくフォルダ名のみ表示する

フォルダ名のみ表示する処理は、LINQを使って配列に変換することもできます。

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

class Program
{
static void Main()
{
string targetPath = @"C:\Work";

string[] folderNames = Directory.GetDirectories(targetPath)
.Select(path => Path.GetFileName(path))
.ToArray();

foreach (string folderName in folderNames)
{
Console.WriteLine(folderName);
}
}
}

Selectを使うことで、取得したフルパスをフォルダ名に変換しています。

画面表示や一覧表示のためにフォルダ名だけが欲しい場合は、この書き方が便利です。

6-3. LINQで条件に合うディレクトリだけ抽出する

Directory.GetDirectoriesで取得した結果は配列なので、LINQでさらに絞り込めます。

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

class Program
{
static void Main()
{
string targetPath = @"C:\Work";

var directories = Directory.GetDirectories(targetPath)
.Where(path => Path.GetFileName(path).Contains("Project"));

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

この例では、フォルダ名にProjectを含むものだけを抽出しています。

検索パターンでも似たような絞り込みはできますが、LINQを使うと複数条件を組み合わせやすくなります。

C#
var directories = Directory.GetDirectories(targetPath)
.Where(path => Path.GetFileName(path).StartsWith("Project"))
.Where(path => !Path.GetFileName(path).Contains("Old"));

この例では、Projectで始まり、かつOldを含まないフォルダだけを取得します。

6-4. 取得したディレクトリ一覧を配列やListに変換する

Directory.GetDirectoriesの戻り値は最初から配列です。

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

List<string>として扱いたい場合は、ToListを使います。

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

class Program
{
static void Main()
{
List<string> directoryList = Directory.GetDirectories(@"C:\Work")
.ToList();
}
}

あとから要素を追加・削除したい場合は、List<string>に変換すると扱いやすくなります。

C#
directoryList.Add(@"C:\Work\NewFolder");
directoryList.Remove(@"C:\Work\OldFolder");

ただし、Directory.GetDirectoriesで取得した結果は実際のファイルシステムの状態を表す文字列です。Listから削除しても、実際のフォルダが削除されるわけではありません。

6-5. 更新日時や作成日時で並び替える

更新日時や作成日時で並び替えたい場合は、DirectoryInfoを組み合わせます。

更新日時の新しい順に並べる例です。

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

class Program
{
static void Main()
{
string targetPath = @"C:\Work";

var directories = Directory.GetDirectories(targetPath)
.Select(path => new DirectoryInfo(path))
.OrderByDescending(dir => dir.LastWriteTime);

foreach (DirectoryInfo dir in directories)
{
Console.WriteLine($"{dir.Name} - {dir.LastWriteTime}");
}
}
}

作成日時の古い順に並べる場合は、CreationTimeを使います。

C#
var directories = Directory.GetDirectories(targetPath)
.Select(path => new DirectoryInfo(path))
.OrderBy(dir => dir.CreationTime);

Directory.GetDirectoriesはパス文字列を返すメソッドですが、DirectoryInfoに変換すれば、更新日時、作成日時、属性などの情報を扱いやすくなります。

7. 例外・エラーへの対処方法

Directory.GetDirectoriesはファイルシステムにアクセスするため、指定パスが存在しない、アクセス権限がない、パスが不正といった理由で例外が発生することがあります。

実務では、必ず例外処理や事前チェックを考慮しましょう。

7-1. DirectoryNotFoundExceptionが発生する原因と対処

DirectoryNotFoundExceptionは、指定したディレクトリが存在しない場合などに発生します。

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

このように存在しないパスを指定すると、例外が発生する可能性があります。

対処方法としては、事前にDirectory.Existsで存在確認を行います。

C#
string path = @"C:\NotExists";

if (Directory.Exists(path))
{
string[] directories = Directory.GetDirectories(path);
}
else
{
Console.WriteLine("指定したフォルダは存在しません。");
}

ユーザー入力のパスを扱う場合は、特に存在確認を行うのがおすすめです。

7-2. UnauthorizedAccessExceptionが発生する原因と対処

UnauthorizedAccessExceptionは、アクセス権限がないフォルダを取得しようとした場合に発生します。

たとえば、管理者権限が必要なフォルダや、他ユーザー専用のフォルダにアクセスしようとすると発生することがあります。

C#
try
{
string[] directories = Directory.GetDirectories(
@"C:\System Volume Information"
);
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("アクセス権限がありません。");
}

Directory.GetDirectoriesの例外として、呼び出し元に必要なアクセス許可がない場合にUnauthorizedAccessExceptionが発生することがあります。

再帰検索では、途中のサブフォルダでアクセス拒否が発生することもあります。そのため、SearchOption.AllDirectoriesを使う場合は特に注意が必要です。

7-3. パスがnullまたは空文字の場合の注意点

pathnullを指定すると、例外の原因になります。

C#
string path = null;

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

また、空文字や不正なパスも問題になります。

C#
string path = "";

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

ユーザー入力を受け取る場合は、string.IsNullOrWhiteSpaceでチェックしておくと安全です。

C#
string path = "";

if (string.IsNullOrWhiteSpace(path))
{
Console.WriteLine("パスが入力されていません。");
return;
}

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

パスがnullの場合や、バージョンによっては空文字・不正文字を含む場合に例外が発生することがあります。

7-4. try-catchで安全にディレクトリ一覧を取得する

実務では、try-catchを使って安全に処理するのがおすすめです。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = @"C:\Work";

try
{
string[] directories = Directory.GetDirectories(path);

foreach (string directory in directories)
{
Console.WriteLine(directory);
}
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("指定したフォルダが見つかりません。");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("フォルダにアクセスする権限がありません。");
}
catch (IOException ex)
{
Console.WriteLine($"入出力エラーが発生しました: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"予期しないエラーが発生しました: {ex.Message}");
}
}
}

Directory.GetDirectoriesでは、存在しないパス、アクセス権限不足、パスがファイル名である場合など、さまざまな理由で例外が発生する可能性があります。

そのため、ユーザーが指定したパスや外部設定ファイルのパスを扱う場合は、例外処理を入れておきましょう。

7-5. Directory.Existsで事前チェックする方法

例外処理に加えて、Directory.Existsで事前チェックする方法も有効です。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string path = @"C:\Work";

if (!Directory.Exists(path))
{
Console.WriteLine("指定したフォルダは存在しません。");
return;
}

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

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

Directory.Existsを使うことで、存在しないフォルダに対してGetDirectoriesを実行するのを防げます。

ただし、存在確認後にフォルダが削除される可能性もあるため、完全に例外を防げるわけではありません。

安全性を高めるには、Directory.Existsによる事前チェックとtry-catchを組み合わせるのがよいでしょう。

8. Directory.GetDirectoriesを使うときの注意点

Directory.GetDirectoriesはシンプルで便利なメソッドですが、ファイルシステムを扱うため、いくつか注意点があります。

特に、存在しないパス、アクセス権限、大量データ、隠しフォルダ、OSごとのパス表記には気を付けましょう。

8-1. 存在しないパスを指定しない

存在しないパスを指定すると、例外が発生する可能性があります。

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

このような指定を避けるために、事前にDirectory.Existsを使います。

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

外部からパスを受け取る場合は、必ず存在確認を行いましょう。

8-2. アクセス権限のないフォルダに注意する

アクセス権限のないフォルダを指定すると、UnauthorizedAccessExceptionが発生する可能性があります。

特に、SearchOption.AllDirectoriesで再帰検索する場合、途中にアクセスできないフォルダがあると処理が止まることがあります。

C#
try
{
string[] directories = Directory.GetDirectories(
@"C:\",
"*",
SearchOption.AllDirectories
);
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("アクセスできないフォルダがあります。");
}

アクセス拒否をスキップしたい場合は、EnumerationOptionsIgnoreInaccessibleを検討します。

C#
var options = new EnumerationOptions
{
RecurseSubdirectories = true,
IgnoreInaccessible = true
};

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

IgnoreInaccessibleは、アクセスが拒否されたファイルまたはディレクトリをスキップするかどうかを指定するプロパティです。

8-3. 大量のディレクトリ取得によるパフォーマンスへの影響

Directory.GetDirectoriesは結果を配列として一括取得します。

そのため、対象フォルダ配下に数万件、数十万件のディレクトリがある場合、メモリ使用量や処理時間に影響が出る可能性があります。

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

すべての結果がそろってから処理する必要がある場合はGetDirectoriesで問題ありません。

一方、1件ずつ処理できればよい場合は、Directory.EnumerateDirectoriesの方が適していることがあります。

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

大量のファイルやディレクトリを扱う場合、EnumerateDirectoriesはコレクション全体を返す前に列挙を開始できるため、GetDirectoriesより効率的な場合があります。

8-4. 隠しフォルダやシステムフォルダを扱う場合の注意点

隠しフォルダやシステムフォルダを扱う場合は、取得対象やアクセス権限に注意が必要です。

取得したディレクトリの属性を確認したい場合は、DirectoryInfoを使います。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string[] directories = Directory.GetDirectories(@"C:\Work");

foreach (string path in directories)
{
DirectoryInfo info = new DirectoryInfo(path);

if ((info.Attributes & FileAttributes.Hidden) != 0)
{
Console.WriteLine($"隠しフォルダ: {info.FullName}");
}
}
}
}

隠しフォルダを除外したい場合は、次のように書けます。

C#
var visibleDirectories = Directory.GetDirectories(@"C:\Work")
.Where(path =>
{
DirectoryInfo info = new DirectoryInfo(path);
return (info.Attributes & FileAttributes.Hidden) == 0;
});

システムフォルダに対してはアクセス拒否が発生することもあるため、例外処理も忘れないようにしましょう。

8-5. WindowsとLinuxでのパス区切り文字の違い

C#はWindowsだけでなく、LinuxやmacOSでも動作します。

Windowsではパス区切り文字に\が使われます。

C:\Work\Project

LinuxやmacOSでは/が使われます。

/home/user/work/project

OSに依存しないコードを書きたい場合は、文字列で区切り文字を直接書くのではなく、Path.Combineを使いましょう。

C#
string path = Path.Combine("Work", "Project");

また、区切り文字を取得したい場合は、Path.DirectorySeparatorCharを使います。

C#
char separator = Path.DirectorySeparatorChar;

クロスプラットフォーム対応のアプリケーションでは、パス文字列を直接連結しないことが重要です。

C#
// 非推奨
string path = basePath + "\\" + folderName;

// 推奨
string path = Path.Combine(basePath, folderName);

9. Directory.EnumerateDirectoriesとの違い

Directory.GetDirectoriesと似たメソッドに、Directory.EnumerateDirectoriesがあります。

どちらもディレクトリ一覧を取得するためのメソッドですが、戻り値と処理タイミングが異なります。

9-1. GetDirectoriesとEnumerateDirectoriesの違い

Directory.GetDirectoriesは、結果をstring[]として一括取得します。

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

一方、Directory.EnumerateDirectoriesは、IEnumerable<string>を返します。

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

EnumerateDirectoriesは、条件に一致するディレクトリのフルパスを列挙可能なコレクションとして返すメソッドです。

大きな違いは、GetDirectoriesは配列全体が返るまで待つ必要があるのに対し、EnumerateDirectoriesは全体が返る前に列挙を開始できる点です。

9-2. 配列で一括取得する場合

取得結果を配列としてまとめて扱いたい場合は、Directory.GetDirectoriesが便利です。

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

Console.WriteLine($"フォルダ数: {directories.Length}");

件数を取得したい、後から何度も同じ配列を参照したい、結果をまとめて処理したい場合に向いています。

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

対象フォルダの数がそれほど多くない場合は、GetDirectoriesで十分です。

9-3. 遅延実行で効率よく取得する場合

1件ずつ処理したい場合や、大量のフォルダを扱う場合は、Directory.EnumerateDirectoriesが適しています。

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

EnumerateDirectoriesIEnumerable<string>を返すため、LINQとも相性がよいです。

C#
var directories = Directory.EnumerateDirectories(@"C:\Work")
.Where(path => Path.GetFileName(path).StartsWith("Project"));

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

すべての結果を配列として保持する必要がない場合は、EnumerateDirectoriesの方が効率的に扱えることがあります。

9-4. 大量データではどちらを使うべきか

大量のディレクトリを扱う場合は、基本的にDirectory.EnumerateDirectoriesを検討するとよいでしょう。

GetDirectoriesは結果を配列として一括取得します。件数が多い場合、配列の作成が終わるまで処理を開始できません。

一方、EnumerateDirectoriesは列挙しながら処理できるため、メモリ効率や初回処理開始の速さで有利になることがあります。

C#
foreach (string directory in Directory.EnumerateDirectories(
@"C:\LargeFolder",
"*",
SearchOption.AllDirectories))
{
Console.WriteLine(directory);
}

ただし、結果を何度も使い回したい場合や、配列として他のメソッドに渡したい場合は、GetDirectoriesToArrayを使っても問題ありません。

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

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

少量のフォルダをまとめて取得したい場合はDirectory.GetDirectories

大量のフォルダを1件ずつ処理したい場合はDirectory.EnumerateDirectories

10. DirectoryInfo.GetDirectoriesとの違い

Directory.GetDirectoriesと似たものに、DirectoryInfo.GetDirectoriesがあります。

どちらもディレクトリ一覧を取得できますが、戻り値が異なります。

10-1. Directory.GetDirectoriesとDirectoryInfo.GetDirectoriesの比較

Directory.GetDirectoriesは、文字列のパス配列を返します。

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

一方、DirectoryInfo.GetDirectoriesは、DirectoryInfo[]を返します。

C#
DirectoryInfo root = new DirectoryInfo(@"C:\Work");
DirectoryInfo[] directories = root.GetDirectories();

文字列としてパスだけ欲しい場合はDirectory.GetDirectoriesがシンプルです。

ディレクトリの名前、フルパス、作成日時、更新日時、属性などを扱いたい場合は、DirectoryInfo.GetDirectoriesが便利です。

10-2. 文字列のパスで取得する場合

パス文字列をそのまま扱いたい場合は、Directory.GetDirectoriesが向いています。

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

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

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

設定ファイルやユーザー入力から受け取ったパスを使って、単純に一覧を取得する場合に使いやすいです。

フォルダ名だけが必要な場合も、Path.GetFileNameを組み合わせれば簡単に取得できます。

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

10-3. DirectoryInfoオブジェクトとして詳細情報を扱う場合

ディレクトリの詳細情報を扱いたい場合は、DirectoryInfoを使うと便利です。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
DirectoryInfo root = new DirectoryInfo(@"C:\Work");

DirectoryInfo[] directories = root.GetDirectories();

foreach (DirectoryInfo directory in directories)
{
Console.WriteLine($"名前: {directory.Name}");
Console.WriteLine($"フルパス: {directory.FullName}");
Console.WriteLine($"作成日時: {directory.CreationTime}");
Console.WriteLine($"更新日時: {directory.LastWriteTime}");
Console.WriteLine();
}
}
}

DirectoryInfoを使うと、パス文字列を毎回DirectoryInfoに変換しなくても、プロパティとして情報を取得できます。

DirectoryInfo.EnumerateDirectoriesには、条件に一致するディレクトリ情報を列挙可能なコレクションとして返すオーバーロードもあります。

10-4. 用途別の使い分け

用途別に整理すると、次のように使い分けると分かりやすいです。

単純にフォルダのパス一覧が欲しい場合は、Directory.GetDirectoriesを使います。

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

フォルダの詳細情報も扱いたい場合は、DirectoryInfo.GetDirectoriesを使います。

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

大量データを効率よく処理したい場合は、Directory.EnumerateDirectoriesDirectoryInfo.EnumerateDirectoriesを検討します。

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

基本的には、パス文字列で十分ならDirectory.GetDirectories、詳細情報が必要ならDirectoryInfo.GetDirectories、大量データならEnumerateDirectoriesと覚えておくとよいでしょう。

11. よくある質問

ここでは、Directory.GetDirectoriesに関するよくある質問をまとめます。

11-1. Directory.GetDirectoriesでファイルは取得できる?

いいえ、Directory.GetDirectoriesではファイルは取得できません。

取得できるのはディレクトリだけです。

ファイルを取得したい場合は、Directory.GetFilesを使います。

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

フォルダとファイルの両方を取得したい場合は、GetDirectoriesGetFilesを組み合わせます。

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

11-2. サブフォルダを含めてすべて取得するには?

サブフォルダを含めてすべて取得するには、SearchOption.AllDirectoriesを指定します。

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

直下だけ取得したい場合は、SearchOption.TopDirectoryOnlyを指定します。

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

11-3. 特定の名前のフォルダだけ取得するには?

特定の名前のフォルダだけ取得したい場合は、searchPatternを指定します。

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

この例では、名前がProjectで始まるフォルダを取得します。

名前にProjectを含むフォルダを取得したい場合は、次のように書きます。

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

完全一致に近い形で特定のフォルダ名を指定したい場合は、次のように書けます。

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

11-4. フォルダ名だけを取得するには?

Directory.GetDirectoriesはパスを含む文字列を返すため、フォルダ名だけが欲しい場合はPath.GetFileNameを使います。

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

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

LINQで配列に変換することもできます。

C#
string[] folderNames = Directory.GetDirectories(@"C:\Work")
.Select(path => Path.GetFileName(path))
.ToArray();

11-5. アクセス拒否エラーを無視して取得できる?

.NETのバージョンや用途によっては、EnumerationOptionsIgnoreInaccessibleを使う方法があります。

C#
var options = new EnumerationOptions
{
RecurseSubdirectories = true,
IgnoreInaccessible = true
};

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

IgnoreInaccessibleは、アクセスが拒否されたファイルやディレクトリをスキップするための設定です。

ただし、すべてのケースで例外処理が不要になるわけではありません。実務では、try-catchも併用するのがおすすめです。

C#
try
{
var options = new EnumerationOptions
{
RecurseSubdirectories = true,
IgnoreInaccessible = true
};

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

foreach (string directory in directories)
{
Console.WriteLine(directory);
}
}
catch (Exception ex)
{
Console.WriteLine($"エラーが発生しました: {ex.Message}");
}

まとめ

Directory.GetDirectoriesは、C#で指定フォルダ内のディレクトリ一覧を取得するための基本的なメソッドです。

最もシンプルな使い方は次のとおりです。

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

検索パターンを指定すれば、特定の名前に一致するフォルダだけを取得できます。

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

サブディレクトリを含めて再帰的に取得したい場合は、SearchOption.AllDirectoriesを指定します。

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

Directory.GetDirectoriesは結果をstring[]として一括取得するため、少量から中程度のフォルダ一覧を扱う場合に便利です。

一方、大量のディレクトリを扱う場合や、1件ずつ効率よく処理したい場合は、Directory.EnumerateDirectoriesも検討しましょう。

また、フォルダの作成日時や更新日時、属性などを扱いたい場合は、DirectoryInfoを組み合わせると便利です。

c# directory.getdirectoriesの基本は、次の3つを押さえておけば十分です。

C#
// 直下のフォルダ一覧を取得
Directory.GetDirectories(path);

// 条件に一致するフォルダを取得
Directory.GetDirectories(path, searchPattern);

// サブフォルダまで再帰的に取得
Directory.GetDirectories(path, searchPattern, SearchOption.AllDirectories);

存在しないパスやアクセス権限のないフォルダでは例外が発生する可能性があるため、Directory.Existsによる事前チェックやtry-catchによる例外処理も忘れずに実装しましょう。