C#を使用してアプリケーションを開発する際、データの保存やログの出力先として新しいフォルダを作成する操作は欠かせない要素の一つです。
本記事では、System.IO名前空間に含まれるDirectory.CreateDirectoryメソッドを中心に、フォルダ作成の基本から応用までを詳しく解説します。
2026年現在の最新の .NET 環境においても、ファイルシステム操作の基本は変わりませんが、クロスプラットフォーム開発やセキュリティ意識の高まりにより、注意すべきポイントがいくつか存在します。
初心者の方でも理解しやすいように、具体的なソースコードを交えながら、安全かつ効率的なフォルダ作成の手法を学んでいきましょう。
また、フォルダの存在確認を行う際の注意点や、例外処理の書き方についても深く掘り下げていきます。
Directory.CreateDirectoryメソッドによる基本的なフォルダ作成
C#でフォルダを作成する最も一般的で簡単な方法は、System.IO.Directory.CreateDirectory メソッドを使用することです。
このメソッドは、指定したパスにフォルダが存在しない場合に新しいフォルダを作成します。
まずは、最もシンプルな実装例を見てみましょう。
using System;
using System.IO;
class Program
{
static void Main()
{
// 作成したいフォルダのパスを指定します
string folderPath = @"C:\SampleData\NewFolder";
try
{
// フォルダを作成します
Directory.CreateDirectory(folderPath);
Console.WriteLine("フォルダが正常に作成されました。");
}
catch (Exception ex)
{
Console.WriteLine($"エラーが発生しました: {ex.Message}");
}
}
}
フォルダが正常に作成されました。
このコードの注目すべき点は、指定したパスの親フォルダが存在しない場合でも、それらを一括で作成してくれるという性質です。
例えば、C:\SampleData というフォルダが存在しなくても、上記のコードを実行すれば SampleData と NewFolder の両方が自動的に生成されます。
これは「再帰的作成」と呼ばれ、開発者が一階層ずつフォルダの有無を確認する手間を省いてくれます。
また、このメソッドは、既にフォルダが存在している場合に呼び出しても、例外をスローせずに既存のフォルダ情報を返すという動作をします。
そのため、作成前に必ずしも存在チェックを行う必要はありませんが、ロジック上で存在の有無を切り分けたい場合には注意が必要です。
絶対パスと相対パスの使い分け
フォルダを指定する際には、絶対パスと相対パスのどちらも利用可能です。
絶対パスは C:\Users\Documents\Target のようにドライブレターから記述する方法で、場所が固定されるため確実性が高いです。
一方、相対パスは実行ファイルがある場所を起点として .\Data\Logs のように記述します。
クラウド環境やコンテナ環境での実行を想定する場合、環境によってドライブ構成が異なるため、相対パスや環境変数を用いたパス指定が推奨されます。
フォルダの存在確認を行う Directory.Exists メソッド
フォルダを作成する前に、そのフォルダが既に存在するかどうかを確認したい場合には Directory.Exists メソッドを使用します。
このメソッドは、指定したパスが存在し、かつそれがフォルダである場合に true を返します。
以下のサンプルコードは、存在確認を行ってから処理を分岐させる例です。
using System;
using System.IO;
string path = @"C:\SampleData\Config";
if (Directory.Exists(path))
{
Console.WriteLine("フォルダは既に存在します。作成をスキップします。");
}
else
{
Directory.CreateDirectory(path);
Console.WriteLine("新しいフォルダを作成しました。");
}
一見するとこの方法は非常に丁寧で安全に見えますが、マルチスレッド環境や複数のプロセスが同時に動くシステムでは注意が必要です。
「存在確認」から「作成」までの僅かな間に、別のプロセスがフォルダを作成してしまうという、いわゆる競合状態 (Race Condition) が発生する可能性があるからです。
そのため、厳密な整合性が求められるプログラムでは、事前にチェックを行わず、直接 Directory.CreateDirectory を実行し、発生した例外を try-catch で処理する手法が取られることもあります。
DirectoryInfoクラスを使用したフォルダ作成と操作
Directory クラスは静的メソッドを提供しますが、特定のフォルダに対して複数の操作を連続して行う場合は DirectoryInfo クラスを利用するのが便利です。
DirectoryInfo はインスタンスを作成して利用するため、フォルダの属性情報や作成日時などのプロパティに効率よくアクセスできます。
using System;
using System.IO;
DirectoryInfo di = new DirectoryInfo(@"C:\Work\ProjectA");
if (!di.Exists)
{
// インスタンスメソッドで作成
di.Create();
Console.WriteLine("フォルダを作成しました。");
}
// 属性を読み取ったり変更したりするのが容易
Console.WriteLine($"作成日時: {di.CreationTime}");
大量のフォルダ情報をループ内で処理する場合など、オブジェクトとして情報を保持し続けたいシーンでは DirectoryInfo の方がパフォーマンス上のメリットを得られることがあります。
一方で、単発のフォルダ作成であれば、簡潔に記述できる Directory.CreateDirectory で十分です。
フォルダ作成時に発生する主な例外とその対策
ファイルシステムの操作には常にエラーのリスクが伴います。
フォルダ作成時に考慮すべき代表的な例外を以下の表にまとめました。
| 例外名 | 発生する主な原因 |
|---|---|
| UnauthorizedAccessException | アクセス権限がない場所への作成、または読み取り専用属性。 |
| PathTooLongException | パスの長さがシステム定義の最大値を超えている。 |
| DirectoryNotFoundException | 指定されたパスが無効、またはドライブが見つからない。 |
| IOException | パスと同じ名前のファイルが既に存在する、またはディスクフル。 |
| ArgumentException | パスに禁止文字が含まれている、または空の文字列。 |
特に UnauthorizedAccessException は、Windowsのシステムフォルダや他のユーザーのディレクトリにアクセスしようとした際に頻繁に発生します。
アプリケーションを一般ユーザー権限で実行している場合、C:\Program Files などの配下には自由にフォルダを作成できません。
また、「同名のファイル」が既に存在する場合にフォルダを作成しようとすると IOException が発生するという点も見落としやすいポイントです。
これらの例外を適切にキャッチし、ユーザーに分かりやすいエラーメッセージを表示することが、堅牢なアプリケーション作成の第一歩となります。
パスを安全に結合する Path.Combine と Path.Join
フォルダを作成する際、複数の文字列を連結してパスを生成することがよくあります。
しかし、文字列の足し算 (path1 + "\\" + path2) でパスを作ると、区切り文字の重複や欠落によるバグの原因になります。
C#では System.IO.Path.Combine メソッドを使用することで、実行環境に応じた適切な区切り文字 (Windowsなら \、Linuxなら /) でパスを結合できます。
string root = @"C:\MyApp";
string sub = "Data";
string name = "User01";
// 安全にパスを結合
string fullPath = Path.Combine(root, sub, name);
Directory.CreateDirectory(fullPath);
.NET Core 以降では Path.Join というメソッドも追加されました。
Path.Combine は「引数に絶対パスが含まれていると、それ以前の引数を破棄する」という仕様がありますが、Path.Join は純粋に文字列を結合します。
意図しないパスの切り捨てを防ぎたい場合は Path.Join の使用を検討してください。
特殊なフォルダパスの取得
アプリケーションの設定ファイルや一時ファイルを保存する場合、任意の場所にフォルダを作るのではなく、OSが推奨する場所を使用するのがマナーです。
Environment.GetFolderPath を使用すると、マイドキュメントや AppData といった特殊フォルダのパスを取得できます。
using System;
using System.IO;
// ユーザーの AppData フォルダを取得
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string myAppPath = Path.Combine(appData, "MyApplicationName");
// ユーザー設定用フォルダを作成
Directory.CreateDirectory(myAppPath);
このように OS の慣習に従うことで、セキュリティソフトによる誤検知を防ぎ、ユーザーごとのデータ隔離も正しく行えるようになります。
一時的な作業用フォルダが必要な場合は、Path.GetTempPath() を利用してシステムの一時フォルダ内に作成するのがベストプラクティスです。
フォルダ名に使用できない文字のチェック
ユーザー入力をフォルダ名にする場合、禁止されている文字が含まれていないかチェックする必要があります。
Windowsでは / : * ? " < > | といった文字をフォルダ名に使用できません。
Path.GetInvalidPathChars や Path.GetInvalidFileNameChars メソッドを使用すると、これらの禁止文字の配列を取得できます。
string userInput = "User/Data";
char[] invalidChars = Path.GetInvalidFileNameChars();
if (userInput.IndexOfAny(invalidChars) >= 0)
{
Console.WriteLine("フォルダ名に無効な文字が含まれています。");
}
else
{
Directory.CreateDirectory(Path.Combine(@"C:\Storage", userInput));
}
無効な文字を含んだまま作成を試みると ArgumentException が発生するため、事前にバリデーションを行うことでアプリのクラッシュを未然に防ぐことができます。
非同期処理とファイルシステム
2026年現在のプログラミングにおいて、UIスレッドをブロックしない非同期処理 (async/await) は一般的です。
しかし、意外なことに .NET の標準ライブラリには Directory.CreateDirectoryAsync というメソッドは存在しません。
これは、フォルダ作成という操作自体がファイルシステムにおいて非常に高速であり、OSレベルでの非同期APIの恩恵が少ないためです。
もし大量のフォルダを作成するために UI がフリーズするのを避けたい場合は、Task.Run を使用してバックグラウンドスレッドで実行するのが標準的な解決策となります。
public async Task CreateFoldersAsync(List<string> paths)
{
await Task.Run(() =>
{
foreach (var path in paths)
{
Directory.CreateDirectory(path);
}
});
}
ただし、ファイルI/Oを並列化しすぎるとディスクのI/O待ちが発生し、逆にパフォーマンスが低下する恐れがあるため注意してください。
まとめ
C#でのフォルダ作成は Directory.CreateDirectory を使用することで、非常にシンプルかつ直感的に実装できます。
基本となる System.IO 名前空間の活用に加え、Path クラスを用いた安全なパス操作を組み合わせることが重要です。
また、実務的なアプリケーションでは、権限不足やパスの長さ制限、禁止文字の混入といった例外に対する備えが欠かせません。
今回解説した存在確認の注意点や DirectoryInfo との使い分け、さらには特殊フォルダの活用といった知識は、Windows環境だけでなく .NET が動作する Linux や macOS での共通スキルとなります。
安全でクリーンなファイル操作を心がけ、メンテナンス性の高いコードを目指しましょう。
