C# Tips | ファイル・ディレクトリ操作:ディレクトリ作成

C sharp C#
スポンサーリンク

はじめに なぜ「ディレクトリ作成」が業務で重要なのか

業務システムでは、ログ出力フォルダ、バックアップフォルダ、インポート用フォルダ、エクスポート用フォルダなど、「フォルダが存在していること」を前提にした処理が山ほどあります。
ところが、サーバー移行や環境構築のミス、権限設定の違いなどでフォルダが存在しないと、処理がいきなり失敗し、バッチが止まったり、ログが出なかったりします。

そこで重要になるのが、「必要なディレクトリを、コード側で確実に作る」ユーティリティです。
C# では System.IO.Directory.CreateDirectory を使うことで、ディレクトリ作成をシンプルに、かつ安全に実装できます。
ここでは、プログラミング初心者向けに、基本から実務で使えるユーティリティ化まで、丁寧にかみ砕いて解説していきます。


基本のメソッド Directory.CreateDirectory を理解する

Directory.CreateDirectory の最もシンプルな使い方

まずは、Directory.CreateDirectory の一番シンプルな例を見てみましょう。

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string folderPath = @"C:\logs\app";

        Directory.CreateDirectory(folderPath);

        Console.WriteLine("ディレクトリ作成を実行しました。");
    }
}
C#

このコードは、「C:\logs\app というディレクトリを作成する」という意味です。
ここでとても重要なポイントがひとつあります。
それは、「指定したディレクトリが既に存在していても、Directory.CreateDirectory は例外を投げず、そのまま正常終了する」という挙動です。

つまり、「なければ作る・あれば何もしない」という動きになっています。
この性質のおかげで、「存在チェック」と「作成」を分けずに、安心して一行で書ける場面が多くなります。

using System.IO を忘れない

Directory クラスは System.IO 名前空間に属しています。
そのため、ファイル・ディレクトリ操作を行うクラスでは、ファイルの先頭付近に次の一行を書いておくのが定番です。

using System.IO;
C#

これを書き忘れると、Directory に赤い波線が出て「型または名前空間の名前 ‘Directory’ が見つかりません」といったコンパイルエラーになります。
「ファイル・ディレクトリ操作=using System.IO;」とセットで覚えてしまうと楽です。


ネストしたディレクトリもまとめて作成できる

中間フォルダがなくても一気に作ってくれる

Directory.CreateDirectory は、指定したパスの途中に存在しないフォルダがあっても、まとめて作成してくれます。
たとえば、次のようなコードを考えてみます。

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string folderPath = @"C:\backup\2025\01\sales";

        Directory.CreateDirectory(folderPath);

        Console.WriteLine("ネストしたディレクトリを作成しました。");
    }
}
C#

このとき、C:\backup しか存在していなくても、202501sales というフォルダを階層ごと一気に作ってくれます。
中間フォルダを一つずつ作る必要はありません。

この「途中のフォルダもまとめて作る」という性質は、年月別のアーカイブフォルダや、顧客ごとのサブフォルダなど、階層構造を持つフォルダ設計で非常に役立ちます。

戻り値の DirectoryInfo について

Directory.CreateDirectory は、作成した(または既に存在していた)ディレクトリを表す DirectoryInfo オブジェクトを返します。

DirectoryInfo info = Directory.CreateDirectory(folderPath);
Console.WriteLine(info.FullName);
C#

初心者のうちは、戻り値を無視しても問題ありません。
ただし、将来的に「ディレクトリの属性を変えたい」「作成したディレクトリの情報を詳しく扱いたい」といった場面では、この DirectoryInfo が役に立ちます。


実務で使える「存在保証」ユーティリティ

EnsureDirectoryExists という発想

業務コードでは、「このフォルダは必ず存在していてほしい」という場所がたくさんあります。
ログ出力フォルダ、インポートファイルの受け取りフォルダ、バックアップフォルダなどが典型例です。

そのたびに Directory.ExistsDirectory.CreateDirectory を書くのではなく、「存在を保証する」ユーティリティメソッドを用意しておくと、コードがかなりスッキリします。

using System;
using System.IO;

public static class DirectoryUtil
{
    public static void EnsureDirectoryExists(string folderPath)
    {
        DirectoryInfo info = Directory.CreateDirectory(folderPath);
        Console.WriteLine($"ディレクトリの存在を保証しました: {info.FullName}");
    }
}
C#

使い方の例は次の通りです。

class Program
{
    static void Main()
    {
        string logFolder = @"C:\logs\app";

        DirectoryUtil.EnsureDirectoryExists(logFolder);

        Console.WriteLine("ここから先でログファイルを書き出す処理を行うイメージです。");
    }
}
C#

ここで深掘りしたいポイントは、「存在チェックと作成を分けずに、一つのメソッドにまとめている」ことです。
Directory.CreateDirectory 自体が「なければ作る・あれば何もしない」という安全な挙動を持っているため、
ユーティリティ側もシンプルに書けます。

ログやエラー処理を組み込んだバージョン

もう少し実務寄りにするなら、ログ出力や例外処理を組み込んだバージョンもよく使われます。

using System;
using System.IO;

public static class DirectoryUtil
{
    public static DirectoryInfo EnsureDirectoryExistsWithLog(string folderPath, Action<string>? log = null)
    {
        try
        {
            DirectoryInfo info = Directory.CreateDirectory(folderPath);
            log?.Invoke($"[INFO] ディレクトリの存在を保証しました: {info.FullName}");
            return info;
        }
        catch (UnauthorizedAccessException ex)
        {
            log?.Invoke($"[ERROR] ディレクトリ作成に失敗しました(権限エラー): {folderPath} / {ex.Message}");
            throw;
        }
        catch (Exception ex)
        {
            log?.Invoke($"[ERROR] ディレクトリ作成に失敗しました: {folderPath} / {ex.Message}");
            throw;
        }
    }
}
C#

使い方の例は次の通りです。

class Program
{
    static void Main()
    {
        string exportFolder = @"C:\data\export";

        DirectoryUtil.EnsureDirectoryExistsWithLog(
            exportFolder,
            message => Console.WriteLine(message)
        );

        Console.WriteLine("ここから先でエクスポートファイルを出力する処理を行うイメージです。");
    }
}
C#

ここでのポイントは、「成功・失敗をログに残しつつ、致命的なエラーは例外として上に伝える」という設計です。
業務システムでは、「なぜフォルダが作れなかったのか」を後から追えるようにしておくことがとても重要です。


パスの組み立てと設定値との連携

Path.Combine で安全にパスを組み立てる

ディレクトリ作成でよくあるのが、「ベースフォルダ+サブフォルダ名」を組み合わせてパスを作るパターンです。
文字列連結で baseFolder + "\\" + subFolder のように書くと、区切り文字の重複や抜けでミスしやすくなります。

C# では Path.Combine を使うことで、OS に合わせて安全にパスを組み立てられます。

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string baseFolder = @"C:\logs";
        string appName = "OrderService";

        string appLogFolder = Path.Combine(baseFolder, appName);

        Directory.CreateDirectory(appLogFolder);

        Console.WriteLine("アプリケーション別ログフォルダを作成しました: " + appLogFolder);
    }
}
C#

このようにしておくと、「アプリケーション名ごとにログフォルダを分ける」といった設計が簡単に実現できます。
削除や移動と同様、ディレクトリ作成でも「パスの組み立てを安全に行う」ことは非常に重要です。

設定ファイルや環境変数との組み合わせ

実務では、フォルダパスをコードにベタ書きするのではなく、設定ファイルや環境変数から読み込むことが多いです。
たとえば、「本番環境では D:\logs、検証環境では C:\logs」のように環境ごとに変えたい場合です。

イメージとしては、次のような流れになります。

設定からベースフォルダを読み込む。
Path.Combine でサブフォルダを組み立てる。
Directory.CreateDirectory または EnsureDirectoryExists で存在を保証する。

これにより、「環境ごとにフォルダパスは違うが、コード側のロジックは同じ」という状態を作れます。
初心者のうちは、まずはベタ書きで動かしてみてから、「これを設定値にしたらどうなるか」を考えてみると理解が深まります。


例外と権限を意識したディレクトリ作成

どんな例外が起こり得るか

ディレクトリ作成では、次のような理由で例外が発生する可能性があります。
権限がなくてその場所にフォルダを作れない、パスが不正(使えない文字が含まれているなど)、同名のファイルが既に存在している、ディスクの状態に問題がある、などです。

例外を意識した書き方の例を見てみましょう。

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string folderPath = @"C:\restricted\logs";

        try
        {
            Directory.CreateDirectory(folderPath);
            Console.WriteLine("ディレクトリ作成に成功しました。");
        }
        catch (UnauthorizedAccessException ex)
        {
            Console.WriteLine("権限エラーが発生しました: " + ex.Message);
        }
        catch (IOException ex)
        {
            Console.WriteLine("入出力エラーが発生しました: " + ex.Message);
        }
        catch (Exception ex)
        {
            Console.WriteLine("想定外のエラーが発生しました: " + ex.Message);
        }
    }
}
C#

実務では、これらのメッセージをログに残しておくことで、「どのフォルダの作成に、どんな理由で失敗したか」を後から追跡できます。
特に権限の問題は、アプリ側だけでは解決できないことも多いため、運用担当者が原因を判断できる情報を残しておくことが重要です。


まとめ 実務で使えるディレクトリ作成の考え方

ディレクトリ作成は、一見シンプルですが、業務システムの安定運用を支える重要な基盤処理です。
「フォルダがなかったせいでログが出ていなかった」「バックアップが保存されていなかった」といったトラブルは、現場で本当に多く発生します。

Directory.CreateDirectory の基本的な挙動(既に存在していても例外を投げず、途中のフォルダもまとめて作ってくれる)を正しく理解すること。
「存在を保証する」ユーティリティ(EnsureDirectoryExists など)を用意し、ログや例外処理を組み込んでおくこと。
パスの組み立てには Path.Combine を使い、設定値や環境ごとの違いを吸収しやすい設計にすること。
権限やパス不正などの例外を意識し、原因が分かるメッセージやログを残すこと。

ここまで押さえておけば、「フォルダがなくてバッチが落ちた」「ログがどこにも出ていなかった」といった、現場でよくあるトラブルをかなり減らせます。

タイトルとURLをコピーしました