C# Tips | ファイル・ディレクトリ操作:ディレクトリ存在チェック

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

はじめに なぜ「ディレクトリ存在チェック」が重要なのか

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

だからこそ、「ディレクトリ(フォルダ)が存在するかを事前に確認する」ユーティリティは、実務でとても重要です。
ここでは C# の Directory.Exists を中心に、初心者にも分かるように丁寧に解説し、業務でそのまま使える形まで落とし込んでいきます。


基本のクラス Directory.Exists を理解する

Directory.Exists の役割

ディレクトリの存在を確認する一番シンプルな方法は、System.IO.Directory.Exists メソッドを使うことです。

using System;
using System.IO;

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

        bool exists = Directory.Exists(folderPath);

        if (exists)
        {
            Console.WriteLine("ディレクトリは存在します。");
        }
        else
        {
            Console.WriteLine("ディレクトリが見つかりません。");
        }
    }
}
C#

Directory.Exists(folderPath) は、指定したパスにディレクトリがあれば true、なければ false を返します。
ここで押さえておきたいポイントは、「存在しないときに例外は投げない」ということです。
あくまで「あるかどうかを確認するだけ」のメソッドなので、存在しないこと自体はエラーではなく、呼び出し側がどう扱うかを決めます。

using System.IO を忘れない

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

using System.IO;
C#

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


実務でよく使うパターン ディレクトリがなければ作る

「存在チェック+作成」は超頻出パターン

業務コードで一番よく出てくるのが、「ディレクトリがなければ作る」というパターンです。
たとえば、ログ出力用フォルダや、日次バッチの出力先フォルダなどは、処理の最初に必ずこの確認を入れておくと安全です。

using System;
using System.IO;

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

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

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

ここで重要なのは、「存在チェック」と「必要なら作成」をセットで考えることです。
業務では、「フォルダがないからエラーで落ちる」のではなく、「フォルダがなければ自動で作る」ほうが現場に優しいことが多いです。

Directory.CreateDirectory の安心ポイント

Directory.CreateDirectory は、指定したパスのディレクトリが存在しない場合に作成しますが、既に存在している場合でも例外を投げず、そのまま正常終了します。
つまり、次のように書いても問題ありません。

Directory.CreateDirectory(logFolder);
C#

この一行だけでも、「なければ作る・あればそのまま」という動きになります。
ただし、ログやメッセージを出したい場合は、先ほどのように Directory.Exists と組み合わせて使うと状況が分かりやすくなります。


ユーティリティメソッドとしてまとめる

存在チェック+作成をひとまとめにする

同じような「存在チェック+作成」コードをあちこちに書くと、修正が大変になります。
そこで、ディレクトリ用のユーティリティメソッドとしてまとめておくと、業務コードがかなりスッキリします。

using System;
using System.IO;

public static class DirectoryUtil
{
    public static void EnsureDirectoryExists(string folderPath)
    {
        if (!Directory.Exists(folderPath))
        {
            Directory.CreateDirectory(folderPath);
            Console.WriteLine($"ディレクトリを作成しました: {folderPath}");
        }
        else
        {
            Console.WriteLine($"ディレクトリは既に存在します: {folderPath}");
        }
    }
}
C#

このユーティリティを使う側のコードは、次のようにシンプルになります。

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

        DirectoryUtil.EnsureDirectoryExists(exportFolder);

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

ポイントは、「ディレクトリの存在確認と作成ロジックを一箇所に集約している」ことです。
将来、「ログの出し方を変えたい」「作成時に権限チェックを追加したい」といった要件が出ても、DirectoryUtil だけを修正すれば済みます。

存在しないときは例外を投げるバージョン

逆に、「このフォルダがないなら処理自体を止めたい」というケースもあります。
たとえば、外部システムとの連携用フォルダなど、運用側が事前に必ず作っておく前提の場所です。

using System;
using System.IO;

public static class DirectoryUtil
{
    public static void EnsureDirectoryExistsOrThrow(string folderPath)
    {
        if (!Directory.Exists(folderPath))
        {
            throw new DirectoryNotFoundException($"必須ディレクトリが見つかりません: {folderPath}");
        }
    }
}
C#

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

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

        try
        {
            DirectoryUtil.EnsureDirectoryExistsOrThrow(importFolder);

            Console.WriteLine("インポートフォルダが存在する前提で処理を開始します。");
        }
        catch (DirectoryNotFoundException ex)
        {
            Console.WriteLine("エラー: " + ex.Message);
            // ログ出力や運用担当への通知などをここに書くことが多い
        }
    }
}
C#

「自動で作るべきフォルダ」と「存在しなければエラーにすべきフォルダ」を分けて考えるのが、実務的な設計のコツです。


パスの扱いと Path.Combine の活用

絶対パスと相対パス

Directory.Exists に渡すパスは、絶対パスでも相対パスでも構いません。

絶対パスの例は次の通りです。

string folderPath = @"C:\data\import";
bool exists = Directory.Exists(folderPath);
C#

相対パスの例は次の通りです。

string folderPath = @"data\import";
bool exists = Directory.Exists(folderPath);
C#

相対パスの場合、「どこからの相対か」が重要です。
コンソールアプリでは通常「カレントディレクトリ」が基準になりますが、実行方法や環境によって変わることがあります。
業務システムでは、設定ファイルや環境変数などで「基準フォルダ」を決めておき、そこからの相対パスで扱う設計もよく使われます。

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

フォルダとサブフォルダ、ファイル名を文字列連結でつなぐと、区切り文字 \ の有無でミスしがちです。
C# では Path.Combine を使うことで、OS に合わせて安全にパスを組み立てられます。

using System.IO;

string baseFolder = @"C:\data";
string subFolder = "import";
string fileName = "sales.csv";

string importFolder = Path.Combine(baseFolder, subFolder);
string filePath = Path.Combine(importFolder, fileName);

bool folderExists = Directory.Exists(importFolder);
bool fileExists = File.Exists(filePath);
C#

このように、ディレクトリ存在チェックとファイル存在チェックを組み合わせると、
「フォルダがあるか」「その中にファイルがあるか」を段階的に確認できます。
業務では、「フォルダがなければ作る」「ファイルがなければエラーにする」といったルールを決めておくと、運用が安定します。


もう一歩踏み込んだ話 権限と例外、タイミングの問題

Directory.Exists では分からないこと

Directory.Exists は、「そのパスにディレクトリが存在するかどうか」を教えてくれますが、
「アクセス権限があるかどうか」までは保証してくれません。
存在していても、権限がなくて中身を列挙できない、ファイルを作れない、といったことはあり得ます。

たとえば、次のようなコードを考えてみます。

string folderPath = @"C:\restricted";

if (Directory.Exists(folderPath))
{
    // ここでファイルを作ろうとしたときに、権限がなくて例外が出る可能性がある
}
C#

この場合、「存在チェックに成功したから絶対に安全」とは言えません。
実務では、「存在チェック」と「実際の操作(ファイル作成や列挙)」の両方を意識して設計する必要があります。

実務的な書き方の例

たとえば、「フォルダがなければ作る」「その中にテストファイルを書いてみる」という形で、
存在と書き込み可能性を同時に確認することもあります。

using System;
using System.IO;

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

        try
        {
            // なければ作成(あればそのまま)
            Directory.CreateDirectory(folderPath);

            // テストとして一時ファイルを書いてみる
            string testFilePath = Path.Combine(folderPath, "write_test.tmp");
            File.WriteAllText(testFilePath, "test");
            File.Delete(testFilePath);

            Console.WriteLine("ディレクトリは存在し、書き込みも可能です。");
        }
        catch (UnauthorizedAccessException ex)
        {
            Console.WriteLine("権限エラー: " + ex.Message);
        }
        catch (IOException ex)
        {
            Console.WriteLine("入出力エラー: " + ex.Message);
        }
    }
}
C#

ここまでやると少し高度ですが、「存在するか」と「実際に使えるか」は別問題だという感覚を持っておくと、
業務システムの設計が一段レベルアップします。


まとめ 実務で使えるディレクトリ存在チェックの考え方

ディレクトリ存在チェックは、一見シンプルですが、業務システムの安定運用に直結する重要な要素です。

Directory.Exists は「存在するかどうか」を確認するだけで、存在しないときに例外は投げないこと。
「なければ作る」パターンでは Directory.CreateDirectory と組み合わせてユーティリティ化すると、コードが読みやすく保守しやすくなること。
「必ず存在していなければならないフォルダ」については、存在しなければ例外を投げる設計も有効であること。
パスの組み立てには Path.Combine を使い、絶対パス・相対パスの基準をチームで揃えておくとトラブルが減ること。
存在チェックだけでは権限やタイミングの問題は完全には防げないため、必要に応じて try-catch で実際の操作も守ること。

ここまで理解できれば、「フォルダがなくてバッチが落ちた」「ログが出力されていなかった」といった、よくある現場トラブルをかなり減らせます。

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