C# Directory.CreateDirectoryの使い方|フォルダ作成・存在チェック・例外処理をサンプルコードで解説

C# Directory.CreateDirectoryの使い方|フォルダ作成・存在チェック・例外処理をサンプルコードで解説

はじめに

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

Directory.CreateDirectoryには、次のような特徴があります。

  • 指定したパスにフォルダを作成できる

  • 親フォルダが存在しなくても、多階層のフォルダをまとめて作成できる

  • フォルダがすでに存在していても、基本的に例外は発生しない

  • 作成したフォルダを表すDirectoryInfoオブジェクトを取得できる

この記事では、C#のDirectory.CreateDirectoryの基本的な使い方から、Directory.Existsによる存在チェック、Path.Combineを使った安全なパスの組み立て、例外処理、実践的なサンプルコードまで解説します。

1. C#のDirectory.CreateDirectoryとは

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

Directory.CreateDirectoryは、指定されたパスにディレクトリを作成するための静的メソッドです。

C#では「フォルダ」と「ディレクトリ」はほぼ同じ意味で使用されます。エクスプローラー上ではフォルダと呼ぶことが多い一方、プログラムやAPIではディレクトリという名称が一般的です。

基本的なコードは次のとおりです。

C#
Directory.CreateDirectory("SampleFolder");

このコードを実行すると、現在の作業フォルダ内にSampleFolderが作成されます。

また、次のように複数階層のパスを指定することも可能です。

C#
Directory.CreateDirectory(@"Data\2026\Reports");

途中のData2026が存在しない場合も、必要な階層がまとめて作成されます。Microsoftの公式ドキュメントでも、パスの一部が無効でない限り、指定されたパス内の未作成ディレクトリがすべて作成されると説明されています。Microsoft Learn

1-2. 使用に必要なSystem.IO名前空間

Directoryクラスを使用するには、ファイルやディレクトリを操作する機能を提供するSystem.IO名前空間を読み込みます。

C#
using System.IO;

これにより、次のようにクラス名だけで記述できます。

C#
Directory.CreateDirectory("SampleFolder");

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

C#
System.IO.Directory.CreateDirectory("SampleFolder");

通常はソースコードの先頭にusing System.IO;を記述する方法が分かりやすいでしょう。

1-3. CreateDirectoryメソッドの構文と戻り値

基本となるCreateDirectoryメソッドの構文は次のとおりです。

C#
public static DirectoryInfo CreateDirectory(string path);

引数pathには、作成するフォルダのパスを指定します。

戻り値は、作成先のディレクトリを表すDirectoryInfoオブジェクトです。

C#
DirectoryInfo directoryInfo =
Directory.CreateDirectory("SampleFolder");

DirectoryInfoからは、フォルダ名やフルパスなどの情報を取得できます。

C#
Console.WriteLine(directoryInfo.Name);
Console.WriteLine(directoryInfo.FullName);
Console.WriteLine(directoryInfo.Exists);

DirectoryInfoは、ディレクトリの作成、移動、列挙などをインスタンス単位で扱うクラスです。Microsoft Learn

1-4. フォルダがすでに存在する場合の動作

Directory.CreateDirectoryに指定したフォルダがすでに存在する場合、新しいフォルダは作成されません。ただし、同じ名前のフォルダが存在するという理由だけで例外が発生することもありません。

C#
Directory.CreateDirectory("SampleFolder");
Directory.CreateDirectory("SampleFolder");

上のコードでは、2回目の呼び出しも正常に終了します。戻り値として、既存のフォルダを表すDirectoryInfoが返されます。Microsoft Learn+1

そのため、単に「対象フォルダを利用可能な状態にしたい」という場合は、事前に存在チェックをせず、直接CreateDirectoryを呼び出せます。

ただし、同じパスにフォルダではなくファイルが存在する場合は、IOExceptionが発生します。

2. Directory.CreateDirectoryでフォルダを作成する基本的な使い方

2-1. 指定したパスにフォルダを作成する

最も基本的な使用例は、文字列でフォルダのパスを指定する方法です。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string folderPath = "SampleFolder";

Directory.CreateDirectory(folderPath);

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

このプログラムを実行すると、現在の作業ディレクトリにSampleFolderが作成されます。

作成後に確認したい場合は、Directory.Existsを使用できます。

C#
Directory.CreateDirectory(folderPath);

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

2-2. 相対パスでフォルダを作成する

相対パスとは、現在の作業ディレクトリを基準としたパスです。

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

Directory.CreateDirectory(folderPath);

Windows環境では、通常、現在の作業ディレクトリの下にData\Imagesが作成されます。

現在の作業ディレクトリは、次のコードで確認できます。

C#
Console.WriteLine(Directory.GetCurrentDirectory());

相対パスの基準は、必ずしも実行ファイルが置かれているフォルダとは限りません。Visual Studio、コマンドプロンプト、タスクスケジューラ、Windowsサービスなど、アプリケーションの実行方法によって現在の作業ディレクトリが変わることがあります。

保存場所を確実に固定したい場合は、絶対パスやAppContext.BaseDirectory、ユーザーの特殊フォルダなどを利用しましょう。

2-3. 絶対パスでフォルダを作成する

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

Windowsでの例は次のとおりです。

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

Directory.CreateDirectory(folderPath);

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

@を使用しない場合は、バックスラッシュを二重に記述します。

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

LinuxやmacOSでは、次のようにスラッシュで始まるパスを使用します。

C#
string folderPath = "/home/user/myapp/data";

なお、書き込み権限のない場所を指定するとUnauthorizedAccessExceptionが発生する可能性があります。

2-4. 多階層のフォルダを一括作成する

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

C#
string folderPath = @"Data\2026\06\Reports";

Directory.CreateDirectory(folderPath);

実行前にDataフォルダが存在しなくても、次の階層が作成されます。

Data
└─ 2026
└─ 06
└─ Reports

階層ごとにCreateDirectoryを呼び出す必要はありません。

C#
// 通常、このように1階層ずつ作成する必要はない
Directory.CreateDirectory("Data");
Directory.CreateDirectory(@"Data\2026");
Directory.CreateDirectory(@"Data\2026\06");
Directory.CreateDirectory(@"Data\2026\06\Reports");

最終的なパスを一度指定するだけで十分です。

2-5. 戻り値のDirectoryInfoを利用する

Directory.CreateDirectoryの戻り値を受け取ると、作成したフォルダの情報を利用できます。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
DirectoryInfo directory =
Directory.CreateDirectory("SampleFolder");

Console.WriteLine($"フォルダ名: {directory.Name}");
Console.WriteLine($"フルパス: {directory.FullName}");
Console.WriteLine($"親フォルダ: {directory.Parent?.FullName}");
Console.WriteLine($"存在するか: {directory.Exists}");
}
}

DirectoryInfoは、フォルダ作成後にファイル一覧を取得したり、サブフォルダを作成したりする場合にも便利です。

C#
DirectoryInfo root =
Directory.CreateDirectory("SampleFolder");

DirectoryInfo child =
root.CreateSubdirectory("ChildFolder");

Console.WriteLine(child.FullName);

作成したフォルダのパスだけが必要な場合は、戻り値を受け取らずに実行しても問題ありません。

C#
Directory.CreateDirectory("SampleFolder");

3. フォルダの存在を確認してから作成する方法

3-1. Directory.Existsでフォルダの存在をチェックする

指定したフォルダが存在するか確認するには、Directory.Existsを使用します。

C#
string folderPath = "SampleFolder";

bool exists = Directory.Exists(folderPath);

Console.WriteLine(exists);

フォルダが存在する場合はtrue、存在しない場合はfalseが返されます。

条件分岐に直接記述することもできます。

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

3-2. フォルダが存在しない場合だけ作成する

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

C#
string folderPath = "SampleFolder";

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

この書き方は、フォルダが新規作成された場合と、すでに存在していた場合で処理を分けたいときに適しています。

例えば、初回作成時だけ初期設定ファイルを出力する場合に利用できます。

C#
string folderPath = "Settings";

if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);

string configPath =
Path.Combine(folderPath, "appsettings.json");

File.WriteAllText(configPath, "{}");
}

3-3. 存在チェックなしでCreateDirectoryを実行できる理由

Directory.CreateDirectoryは、指定したフォルダがすでに存在する場合でも正常に終了するように設計されています。

そのため、フォルダを確実に利用できる状態にすることだけが目的なら、次の1行で十分です。

C#
Directory.CreateDirectory(folderPath);

次のような事前チェックは必須ではありません。

C#
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}

さらに、存在チェックと作成処理の間に別のスレッドやプロセスがフォルダを作成する可能性があります。事前チェックをしても、ファイルシステムの状態がそのまま維持されるとは限りません。

したがって、新規作成かどうかを区別する必要がない場合は、直接CreateDirectoryを呼び出し、必要に応じて例外を処理する方法がシンプルです。

3-4. 存在チェックが必要なケースと不要なケース

存在チェックが必要になる代表的なケースは次のとおりです。

  • 新規作成された場合だけメッセージを表示したい

  • 初回作成時だけ設定ファイルを生成したい

  • 既存フォルダを上書き対象として扱いたくない

  • 既存フォルダと新規フォルダで処理を分けたい

一方、次のようなケースでは存在チェックを省略できます。

  • ログの保存先を確実に用意したい

  • 設定ファイルの保存先を確実に用意したい

  • 一時ファイルの保存先を準備したい

  • フォルダが存在していても同じ処理を続けたい

例えば、ログフォルダの準備は次のように記述できます。

C#
string logDirectory = "Logs";

Directory.CreateDirectory(logDirectory);

string logFilePath =
Path.Combine(logDirectory, "application.log");

File.AppendAllText(
logFilePath,
$"{DateTime.Now:yyyy-MM-dd HH:mm:ss} アプリを起動しました。{Environment.NewLine}"
);

4. パスを安全に組み立ててフォルダを作成する方法

4-1. Path.Combineを使ってパスを結合する

複数の文字列からフォルダパスを組み立てる場合は、文字列の単純な連結ではなくPath.Combineを使用します。

C#
string basePath = @"C:\MyApplication";
string folderName = "Data";

string folderPath =
Path.Combine(basePath, folderName);

Directory.CreateDirectory(folderPath);

Path.Combineは、複数の文字列をパスとして結合するためのメソッドです。Microsoft Learn

次のように、区切り文字を直接付けて連結する方法は避けたほうが安全です。

C#
// 推奨しない
string folderPath = basePath + "\\" + folderName;

Path.Combineなら、パス末尾に区切り文字があるかどうかを意識せずに記述できます。

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

ただし、2番目以降の引数に絶対パスが渡されると、それより前のパス要素が無視されることがあります。ユーザー入力をそのままパス要素として利用せず、絶対パスや区切り文字、..などが含まれていないか検証することが重要です。Microsoft Learn

4-2. 実行ファイルのフォルダを基準に作成する

実行ファイルの配置場所を基準にフォルダを作成する場合は、AppContext.BaseDirectoryを利用できます。

C#
string baseDirectory = AppContext.BaseDirectory;

string dataDirectory =
Path.Combine(baseDirectory, "Data");

Directory.CreateDirectory(dataDirectory);

Console.WriteLine(dataDirectory);

相対パスとは異なり、現在の作業ディレクトリが変わっても、アプリケーションのベースディレクトリを基準にできます。

ただし、アプリケーションのインストール先によっては書き込み権限がない場合があります。特にWindowsのProgram Files内に配置されたアプリケーションでは、実行ファイルと同じ場所へのデータ保存を避け、ユーザーごとのアプリケーションデータフォルダを使うほうが適切です。

4-3. ユーザーごとの特殊フォルダ内に作成する

設定ファイルやログなど、ユーザーごとのデータはEnvironment.GetFolderPathを利用して保存先を取得できます。

C#
string localAppData =
Environment.GetFolderPath(
Environment.SpecialFolder.LocalApplicationData
);

string appDirectory = Path.Combine(
localAppData,
"SampleCompany",
"SampleApplication"
);

Directory.CreateDirectory(appDirectory);

Console.WriteLine(appDirectory);

Environment.GetFolderPathは、指定した特殊フォルダへのパスを取得するメソッドです。対象フォルダが物理的に存在しない場合などは、空文字列が返ることがあります。Microsoft Learn

より堅牢にする場合は、取得結果も確認します。

C#
string localAppData =
Environment.GetFolderPath(
Environment.SpecialFolder.LocalApplicationData
);

if (string.IsNullOrWhiteSpace(localAppData))
{
throw new InvalidOperationException(
"アプリケーションデータフォルダを取得できませんでした。"
);
}

string appDirectory =
Path.Combine(localAppData, "SampleApplication");

Directory.CreateDirectory(appDirectory);

ユーザーごとの設定データにはApplicationData、ローカル端末だけで使用するキャッシュやログにはLocalApplicationDataなど、データの用途に合わせて選択します。

4-4. 日付やユーザー入力をフォルダ名に使用する

日付をフォルダ名にする場合は、パスで使用しやすい書式を指定します。

C#
string dateFolderName =
DateTime.Now.ToString("yyyy-MM-dd");

string folderPath =
Path.Combine("Reports", dateFolderName);

Directory.CreateDirectory(folderPath);

日時を含める場合は、コロンを使用しない書式にします。

C#
string dateTimeFolderName =
DateTime.Now.ToString("yyyyMMdd_HHmmss");

string folderPath =
Path.Combine("Backups", dateTimeFolderName);

Directory.CreateDirectory(folderPath);

次のような書式は、Windowsではコロンがパスとして問題になる可能性があるため、フォルダ名には適していません。

C#
// フォルダ名には適さない
string name = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

ユーザー入力をフォルダ名として使用する場合は、入力値をそのまま渡さないようにします。

C#
string userInput = Console.ReadLine() ?? string.Empty;

if (string.IsNullOrWhiteSpace(userInput))
{
Console.WriteLine("フォルダ名を入力してください。");
return;
}

string folderPath =
Path.Combine("UserFolders", userInput);

Directory.CreateDirectory(folderPath);

このコードだけでは、区切り文字や..による意図しないパス移動を防げません。実際のアプリケーションでは、使用可能な文字を限定する、長さを制限する、予約名を拒否するなどの検証が必要です。

4-5. 使用できない文字を含むフォルダ名に注意する

フォルダ名に使用できない文字はOSによって異なります。Windowsでは、一般的に次の文字をフォルダ名の一部として使用できません。

\ / : * ? " < > |

個別のフォルダ名に使用できない文字は、Path.GetInvalidFileNameCharsで取得できます。

C#
char[] invalidChars =
Path.GetInvalidFileNameChars();

foreach (char invalidChar in invalidChars)
{
Console.WriteLine((int)invalidChar);
}

入力値から使用できない文字を置換する例は次のとおりです。

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

class Program
{
static void Main()
{
string input = "売上:2026/06";

char[] invalidChars =
Path.GetInvalidFileNameChars();

string safeName = new string(
input
.Select(c =>
invalidChars.Contains(c) ? '_' : c)
.ToArray()
);

string folderPath =
Path.Combine("Reports", safeName);

Directory.CreateDirectory(folderPath);

Console.WriteLine(folderPath);
}
}

ただし、無効な文字を除去するだけでは十分でないケースもあります。WindowsではCONPRNAUXNULCOM1などが予約名として扱われます。

また、ユーザー入力が...でないこと、ルート付きパスではないこと、パス区切り文字を含まないことも確認しましょう。

C#
static bool IsValidFolderName(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return false;
}

if (name is "." or "..")
{
return false;
}

return name.IndexOfAny(
Path.GetInvalidFileNameChars()
) < 0;
}

5. Directory.CreateDirectoryで発生する例外と対処法

Directory.CreateDirectoryでは、パスの内容、アクセス権限、ファイルシステムの状態などによって例外が発生します。

Microsoftの公式ドキュメントでは、主にIOExceptionUnauthorizedAccessExceptionArgumentExceptionArgumentNullExceptionPathTooLongExceptionDirectoryNotFoundExceptionNotSupportedExceptionが挙げられています。Microsoft Learn

5-1. UnauthorizedAccessExceptionが発生する原因と対処

UnauthorizedAccessExceptionは、フォルダを作成するために必要なアクセス権限がない場合に発生します。

主な原因は次のとおりです。

  • 書き込み権限がないフォルダを指定している

  • システムで保護されたフォルダを指定している

  • アプリケーションの実行ユーザーに権限がない

  • 読み取り専用の共有先を指定している

C#
try
{
Directory.CreateDirectory(
@"C:\Windows\SampleFolder"
);
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine(
$"フォルダを作成する権限がありません: {ex.Message}"
);
}

対処方法として、ユーザーが書き込めるLocalApplicationDataやドキュメントフォルダなどを保存先に使用します。

管理者権限での実行を前提にするよりも、通常ユーザーの権限で書き込める保存先を選ぶほうが安全です。

5-2. ArgumentExceptionが発生する原因と対処

ArgumentExceptionは、引数として渡したパスの形式が不正な場合などに発生します。

C#
try
{
Directory.CreateDirectory("不正なパス");
}
catch (ArgumentException ex)
{
Console.WriteLine(
$"パスの形式が正しくありません: {ex.Message}"
);
}

.NETのバージョンによって、空文字列や無効な文字に対する検証動作が異なる場合があります。特に古い.NET Frameworkや.NET Core 2.1より前のバージョンでは、空文字列、空白だけの文字列、無効な文字を含むパスなどがArgumentExceptionの原因として記載されています。Microsoft Learn+1

例外だけに頼らず、事前に入力値を確認することが重要です。

C#
if (string.IsNullOrWhiteSpace(folderPath))
{
Console.WriteLine(
"フォルダパスを指定してください。"
);
return;
}

Directory.CreateDirectory(folderPath);

5-3. ArgumentNullExceptionが発生する原因と対処

ArgumentNullExceptionは、pathnullを渡した場合に発生します。

C#
string? folderPath = null;

try
{
Directory.CreateDirectory(folderPath!);
}
catch (ArgumentNullException ex)
{
Console.WriteLine(
$"パスがnullです: {ex.Message}"
);
}

ユーザー入力や設定ファイルからパスを取得する場合は、nullや空文字列を確認してから使用します。

C#
if (string.IsNullOrWhiteSpace(folderPath))
{
throw new ArgumentException(
"フォルダパスが指定されていません。",
nameof(folderPath)
);
}

Directory.CreateDirectory(folderPath);

nullable参照型を有効にしているプロジェクトでは、変数をstring?として扱い、コンパイル時の警告も活用しましょう。

5-4. PathTooLongExceptionが発生する原因と対処

PathTooLongExceptionは、指定したパスやフォルダ名が、実行環境で扱える長さを超えた場合に発生します。

C#
try
{
string longName = new string('a', 500);
Directory.CreateDirectory(
Path.Combine("Data", longName)
);
}
catch (PathTooLongException ex)
{
Console.WriteLine(
$"パスが長すぎます: {ex.Message}"
);
}

対処方法は次のとおりです。

  • フォルダ名を短くする

  • 保存先の階層を浅くする

  • ユーザー入力の最大文字数を制限する

  • 長い識別子をハッシュ値や短いIDに置き換える

  • 対象OSや.NETランタイムの長いパス対応状況を確認する

パス長の制限はOS、ファイルシステム、アプリケーション設定、使用中のAPIなどに左右されるため、特定の固定値だけを前提にしない設計が必要です。

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

DirectoryNotFoundExceptionは、指定されたパス自体が無効な場合に発生する可能性があります。

例えば、存在しないドライブや、接続されていないドライブを指定した場合です。

C#
try
{
Directory.CreateDirectory(
@"Z:\SampleFolder"
);
}
catch (DirectoryNotFoundException ex)
{
Console.WriteLine(
$"指定したドライブまたはパスが見つかりません: {ex.Message}"
);
}

CreateDirectoryは途中の親フォルダを自動的に作成します。そのため、単に親フォルダが存在しないだけなら通常は問題になりません。

確認すべきなのは、次のような項目です。

  • ドライブが存在するか

  • ネットワークドライブが接続されているか

  • パスのルート部分が正しいか

  • リムーバブルメディアが挿入されているか

  • ネットワーク共有が利用可能か

5-6. IOExceptionが発生する原因と対処

IOExceptionは、ファイルシステム上の入出力エラーが発生した場合にスローされます。

代表的な原因は、作成しようとしたフォルダと同じパスにファイルが存在するケースです。

C#
string path = "Sample";

File.WriteAllText(path, "test");

try
{
Directory.CreateDirectory(path);
}
catch (IOException ex)
{
Console.WriteLine(
$"入出力エラーが発生しました: {ex.Message}"
);
}

事前に同名ファイルを確認する場合は、File.Existsを使用します。

C#
if (File.Exists(folderPath))
{
Console.WriteLine(
"同じパスにファイルが存在します。"
);
return;
}

Directory.CreateDirectory(folderPath);

ほかにも、ネットワーク共有の障害やファイルシステム側の問題などでIOExceptionが発生する可能性があります。

5-7. NotSupportedExceptionが発生する原因と対処

NotSupportedExceptionは、サポートされていない形式のパスが指定された場合に発生します。

Microsoftの公式ドキュメントでは、ドライブ名の一部ではない不正な位置にコロンが含まれる場合などが例として挙げられています。Microsoft Learn

C#
try
{
Directory.CreateDirectory(
@"C:\Data\Test:Folder"
);
}
catch (NotSupportedException ex)
{
Console.WriteLine(
$"サポートされていないパス形式です: {ex.Message}"
);
}

日時をフォルダ名に使うときは、コロンを含まない形式にします。

C#
string folderName =
DateTime.Now.ToString("yyyyMMdd_HHmmss");

外部から受け取ったパスを使用する場合は、対応している形式か、絶対パスとして正しいか、想定したルート内に収まっているかを確認しましょう。

5-8. try-catchを使った例外処理のサンプルコード

Directory.CreateDirectoryの例外を個別に処理するサンプルは次のとおりです。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string? folderPath =
Console.ReadLine();

if (string.IsNullOrWhiteSpace(folderPath))
{
Console.WriteLine(
"フォルダパスを入力してください。"
);
return;
}

try
{
DirectoryInfo directory =
Directory.CreateDirectory(folderPath);

Console.WriteLine(
$"フォルダを準備しました: {directory.FullName}"
);
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine(
$"アクセス権限がありません: {ex.Message}"
);
}
catch (ArgumentException ex)
{
Console.WriteLine(
$"パスの指定が正しくありません: {ex.Message}"
);
}
catch (PathTooLongException ex)
{
Console.WriteLine(
$"パスが長すぎます: {ex.Message}"
);
}
catch (DirectoryNotFoundException ex)
{
Console.WriteLine(
$"ドライブまたはパスが見つかりません: {ex.Message}"
);
}
catch (NotSupportedException ex)
{
Console.WriteLine(
$"サポートされていないパスです: {ex.Message}"
);
}
catch (IOException ex)
{
Console.WriteLine(
$"入出力エラーが発生しました: {ex.Message}"
);
}
}
}

ArgumentNullExceptionArgumentExceptionを継承しているため、両方を個別に処理する場合は、より具体的なArgumentNullExceptionを先に記述します。

C#
try
{
Directory.CreateDirectory(folderPath!);
}
catch (ArgumentNullException ex)
{
Console.WriteLine(
$"パスがnullです: {ex.Message}"
);
}
catch (ArgumentException ex)
{
Console.WriteLine(
$"パスが不正です: {ex.Message}"
);
}

すべての例外を一律にExceptionで処理するだけでは、原因に応じた対応が難しくなります。ただし、アプリケーションの最上位で未処理例外をログに記録する目的なら、最後にExceptionを捕捉する設計も考えられます。

C#
catch (Exception ex)
{
Console.WriteLine(
$"予期しないエラーが発生しました: {ex}"
);
}

6. Directory.CreateDirectoryの実践的なサンプルコード

6-1. アプリケーションの設定フォルダを作成する

アプリケーションの設定ファイルは、ユーザーごとのアプリケーションデータフォルダに保存すると管理しやすくなります。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
string appData =
Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData
);

if (string.IsNullOrWhiteSpace(appData))
{
throw new InvalidOperationException(
"アプリケーションデータフォルダを取得できませんでした。"
);
}

string configDirectory = Path.Combine(
appData,
"SampleCompany",
"SampleApplication"
);

Directory.CreateDirectory(configDirectory);

string configFilePath = Path.Combine(
configDirectory,
"settings.json"
);

if (!File.Exists(configFilePath))
{
File.WriteAllText(
configFilePath,
"""
{
"language": "ja-JP",
"theme": "light"
}
"""
);
}

Console.WriteLine(
$"設定ファイル: {configFilePath}"
);
}
}

このコードでは、設定フォルダは毎回CreateDirectoryで準備し、設定ファイルが存在しない場合だけ初期ファイルを生成しています。

フォルダの存在チェックは不要ですが、設定ファイルを上書きしないためにFile.Existsを使用しています。

6-2. ログ保存用フォルダを作成する

ログファイルを保存する前に、ログ用フォルダを作成する例です。

C#
using System;
using System.IO;
using System.Text;

class Program
{
static void Main()
{
try
{
string localAppData =
Environment.GetFolderPath(
Environment.SpecialFolder.LocalApplicationData
);

if (string.IsNullOrWhiteSpace(localAppData))
{
throw new InvalidOperationException(
"ローカルアプリケーションデータフォルダを取得できませんでした。"
);
}

string logDirectory = Path.Combine(
localAppData,
"SampleApplication",
"Logs"
);

Directory.CreateDirectory(logDirectory);

string logFileName =
$"app_{DateTime.Now:yyyyMMdd}.log";

string logFilePath = Path.Combine(
logDirectory,
logFileName
);

string message =
$"{DateTime.Now:yyyy-MM-dd HH:mm:ss} " +
"アプリケーションを起動しました。" +
Environment.NewLine;

File.AppendAllText(
logFilePath,
message,
Encoding.UTF8
);

Console.WriteLine(
$"ログを出力しました: {logFilePath}"
);
}
catch (UnauthorizedAccessException ex)
{
Console.Error.WriteLine(
$"ログフォルダへの書き込み権限がありません: {ex.Message}"
);
}
catch (IOException ex)
{
Console.Error.WriteLine(
$"ログの出力中にエラーが発生しました: {ex.Message}"
);
}
}
}

ログフォルダがすでに存在していても、CreateDirectoryはそのまま正常に終了します。そのため、アプリケーション起動時やログ出力直前に毎回実行できます。

複数のスレッドやプロセスから同じログファイルへ書き込む場合は、フォルダ作成とは別に、ファイル書き込みの排他制御も検討する必要があります。

6-3. 年月日ごとのフォルダを自動作成する

バックアップ、画像、帳票などを日付ごとに分類する場合は、年月日をパスの各階層として使用できます。

C#
using System;
using System.IO;

class Program
{
static void Main()
{
DateTime targetDate = DateTime.Now;

string baseDirectory = Path.Combine(
AppContext.BaseDirectory,
"Reports"
);

string dailyDirectory = Path.Combine(
baseDirectory,
targetDate.ToString("yyyy"),
targetDate.ToString("MM"),
targetDate.ToString("dd")
);

DirectoryInfo directory =
Directory.CreateDirectory(dailyDirectory);

string reportFilePath = Path.Combine(
directory.FullName,
"report.txt"
);

File.WriteAllText(
reportFilePath,
$"作成日時: {DateTime.Now:yyyy-MM-dd HH:mm:ss}"
);

Console.WriteLine(
$"帳票を保存しました: {reportFilePath}"
);
}
}

例えば、2026年6月20日に実行すると、次のようなフォルダ構成になります。

Reports
└─ 2026
└─ 06
└─ 20
└─ report.txt

1日単位ではなく、月単位のフォルダにする場合は、日付部分を省略します。

C#
string monthlyDirectory = Path.Combine(
baseDirectory,
DateTime.Now.ToString("yyyy"),
DateTime.Now.ToString("MM")
);

Directory.CreateDirectory(monthlyDirectory);

フォルダ名に日時を使用する場合は、カルチャによって変化する既定の文字列表現ではなく、yyyyMMddyyyy-MM-ddのように書式を明示することが重要です。

まとめ

C#でフォルダを作成するには、System.IO.Directory.CreateDirectoryを使用します。

基本的な書き方は次のとおりです。

C#
Directory.CreateDirectory(folderPath);

Directory.CreateDirectoryは、指定したフォルダがすでに存在していても正常に終了します。また、親フォルダが存在しない場合は、必要な階層をまとめて作成できます。

パスを組み立てるときは、文字列を直接連結せず、Path.Combineを使用しましょう。

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

Directory.CreateDirectory(folderPath);

単にフォルダを利用可能な状態にするだけなら、Directory.Existsによる事前チェックは必須ではありません。

C#
Directory.CreateDirectory(folderPath);

新規作成時だけ別の処理を行いたい場合は、存在チェックを組み合わせます。

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

実際のアプリケーションでは、アクセス権限、不正なパス、パス長、同名ファイル、存在しないドライブなどによって例外が発生する可能性があります。ユーザー入力の検証と適切な例外処理を行い、安全にフォルダを作成しましょう。