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

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

はじめに ファイル「存在チェック」はなぜ大事か

業務システムでは、「このファイルがある前提」で処理を書いてしまうと、現場で簡単に事故が起きます。
たとえば「毎朝、前日の売上 CSV を読み込むバッチ」が、ファイルが来ていない日にエラーで落ちる――こういうのは本当によくあります。

だからこそ、「ファイルが存在するかどうかを事前に確認する」ユーティリティは、業務プログラムの安定性を支える超・基本テクニックです。
ここでは C# でのファイル存在チェックを、初心者向けに丁寧に解説しつつ、「実務でどう使うか」まで踏み込みます。


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

File.Exists の役割と特徴

C# でファイルの存在を確認する一番シンプルな方法は、System.IO.File.Exists メソッドを使うことです。

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string path = @"C:\data\sales.csv";

        bool exists = File.Exists(path);

        if (exists)
        {
            Console.WriteLine("ファイルは存在します。");
        }
        else
        {
            Console.WriteLine("ファイルが見つかりません。");
        }
    }
}
C#

File.Exists(path) は、指定したパスにファイルがあれば true、なければ false を返します。
ここで重要なのは、「存在しないときに例外は投げない」という点です。
初心者のうちは「存在しない=例外が飛ぶ」と思いがちですが、File.Exists はあくまで「確認するだけ」のメソッドです。

using System.IO を忘れない

File クラスは System.IO 名前空間に属しています。
そのため、ファイル操作を行うクラスを書くときは、ファイルの先頭付近に

using System.IO;
C#

を書いておくのが定番です。
これを書き忘れると、File に赤い波線が出て「型または名前空間の名前 ‘File’ が見つかりません」と怒られます。


実務を意識した「存在チェック」ユーティリティメソッド

よくあるパターン 単純な存在チェック+メッセージ

業務コードでは、同じような「存在チェック+メッセージ表示(またはログ出力)」が何度も出てきます。
そのたびに File.Existsif 文を書くと、コードが散らばって読みにくくなります。

そこで、「存在チェック専用の小さなメソッド」を用意しておくと、コードがかなりスッキリします。

using System;
using System.IO;

public static class FileUtil
{
    public static bool CheckFileExists(string path)
    {
        if (File.Exists(path))
        {
            Console.WriteLine($"ファイルが見つかりました: {path}");
            return true;
        }
        else
        {
            Console.WriteLine($"ファイルが存在しません: {path}");
            return false;
        }
    }
}
C#

このユーティリティを使う側は、次のように書けます。

class Program
{
    static void Main()
    {
        string path = @"C:\data\sales.csv";

        if (!FileUtil.CheckFileExists(path))
        {
            // 必要ならここで処理を中断したり、別の処理に切り替えたりする
            return;
        }

        // ここまで来たらファイルは存在するとみなしてよい
        Console.WriteLine("ここでファイル読み込み処理を行うイメージです。");
    }
}
C#

ポイントは、「存在チェックのロジック」と「その後の業務処理」を分けていることです。
こうしておくと、存在チェックの仕様を変えたいとき(例:ログの出し方を変える、例外を投げるようにするなど)に、ユーティリティだけを修正すれば済みます。

例外を投げるバージョンもよく使う

「ファイルがなかったら、その時点で処理を止めたい」というケースも多いです。
その場合は、存在しなかったときに例外を投げるユーティリティを用意しておくと便利です。

using System;
using System.IO;

public static class FileUtil
{
    public static void EnsureFileExists(string path)
    {
        if (!File.Exists(path))
        {
            throw new FileNotFoundException($"必須ファイルが見つかりません: {path}", path);
        }
    }
}
C#

使い方は次のようになります。

class Program
{
    static void Main()
    {
        string path = @"C:\data\sales.csv";

        try
        {
            FileUtil.EnsureFileExists(path);

            // ここまで来たらファイルは存在する前提で処理を書ける
            Console.WriteLine("ファイルがある前提で読み込み処理を開始します。");
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine("エラー: " + ex.Message);
            // ログに書く、メール通知する、などの対応をここに書くことも多い
        }
    }
}
C#

「存在しなかったら例外を投げる」というスタイルは、
「このファイルがないなら、そもそもこの処理は成立しない」という重要ファイルに対してよく使われます。


パスの扱いと注意点 絶対パス・相対パス・パス結合

絶対パスと相対パス

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

絶対パスの例:

string path = @"C:\data\sales.csv";
bool exists = File.Exists(path);
C#

相対パスの例:

string path = @"data\sales.csv";
bool exists = File.Exists(path);
C#

ただし相対パスの場合、「どこからの相対か?」が重要になります。
コンソールアプリなら、通常は「実行ファイルがあるフォルダ」ではなく「カレントディレクトリ」が基準になります。
業務システムでは、環境によってカレントディレクトリが変わることもあるため、
「相対パスを使うなら、どこを基準にするか」をチーム内で決めておくと安全です。

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

フォルダとファイル名を文字列連結でつなぐと、"C:\data" + "\sales.csv" のように書きがちですが、
区切り文字の \ を二重に書いてしまったり、逆に抜けてしまったりと、地味なバグの原因になります。

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

using System.IO;

string folder = @"C:\data";
string fileName = "sales.csv";

string path = Path.Combine(folder, fileName);
// 結果: C:\data\sales.csv

bool exists = File.Exists(path);
C#

業務コードでは、「フォルダ設定+ファイル名」の組み合わせが頻出するので、
Path.Combine を使うクセをつけておくと、後々かなり助かります。


Directory.Exists との違いも押さえておく

ファイルとディレクトリは別物

File.Exists は「ファイル」の存在を確認するメソッドです。
一方で、「フォルダ(ディレクトリ)が存在するか」を確認したい場合は、Directory.Exists を使います。

using System.IO;

string folderPath = @"C:\data";

bool folderExists = Directory.Exists(folderPath);
C#

ここで大事なのは、「ファイルとディレクトリは別物として扱う」という意識です。
File.Exists にフォルダパスを渡しても、true にはなりません。
業務でよくあるのは、「フォルダがなければ作る」「ファイルがなければエラーにする」といった組み合わせです。

フォルダがなければ作る+ファイル存在チェックの例

たとえば「ログ出力用フォルダがなければ作る」「ログファイルがあれば追記、なければ新規作成」という処理を考えてみます。

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string logFolder = @"C:\logs";
        string logFileName = "app.log";
        string logPath = Path.Combine(logFolder, logFileName);

        // フォルダがなければ作成
        if (!Directory.Exists(logFolder))
        {
            Directory.CreateDirectory(logFolder);
            Console.WriteLine("ログフォルダを作成しました。");
        }

        // ファイルの存在チェック
        if (File.Exists(logPath))
        {
            Console.WriteLine("ログファイルは既に存在します。追記モードで開く想定です。");
        }
        else
        {
            Console.WriteLine("ログファイルは存在しません。新規作成する想定です。");
        }

        // 実際のログ書き込み処理はここに続くイメージ
    }
}
C#

このように、「フォルダの存在チェック」と「ファイルの存在チェック」をセットで考えられるようになると、
業務でのファイル周りのトラブルをかなり減らせます。


もう一歩踏み込んだ話 例外と「存在チェックのタイミング」

File.Exists だけでは防げないケースがある

少しレベルの高い話ですが、実務では「存在チェックをした直後に、ファイルが消される」こともあり得ます。
たとえば、別プロセスや別ユーザーが同じファイルを操作している場合です。

流れとしてはこうです。

  1. File.Exists(path)true が返る
  2. その直後に、他のプロセスがファイルを削除する
  3. 自分のコードが File.OpenRead(path) などを呼ぶ
  4. 「ファイルが見つかりません」という例外が発生する

このように、「存在チェックをしたからといって、その後の操作が必ず成功するとは限らない」という点は、
実務ではとても重要な考え方です。

実務的な書き方のコツ

実務では、「存在チェック」と「実際の処理」の両方を意識して書きます。

  1. 事前に File.Exists でチェックして、ユーザー向けの分かりやすいメッセージやログを出す
  2. 実際にファイルを開くときは、念のため try-catch で例外も受け止める

例として、読み込み処理を考えてみます。

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string path = @"C:\data\sales.csv";

        if (!File.Exists(path))
        {
            Console.WriteLine("売上ファイルが存在しません。処理を中断します。");
            return;
        }

        try
        {
            string text = File.ReadAllText(path);
            Console.WriteLine("ファイルの読み込みに成功しました。");
            // 読み込んだ内容を解析する処理が続くイメージ
        }
        catch (IOException ex)
        {
            Console.WriteLine("ファイル読み込み中にエラーが発生しました。詳細: " + ex.Message);
            // ログ出力や通知などをここに書く
        }
    }
}
C#

こうしておくと、「そもそもファイルがない」というケースと、
「存在はしていたが、読み込み中に何か問題が起きた」というケースを、
メッセージやログで区別できるようになります。


まとめ 実務で使える「存在チェック」の考え方

ファイル存在チェックは、一見シンプルですが、業務システムではかなり重要な役割を持ちます。

  • File.Exists は「存在するかどうかを調べるだけ」で、存在しないときに例外は投げない
  • よく使うパターンはユーティリティメソッドにまとめると、コードが読みやすく・変更しやすくなる
  • フォルダの存在は Directory.Exists で確認し、必要なら Directory.CreateDirectory で作成する
  • 「存在チェックをしたから絶対に安全」とは限らないので、実際のファイル操作は try-catch で守る

ここまで理解できれば、「ファイルがある前提で書いてしまって、現場で落ちる」という典型的なトラブルはかなり減らせます。

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