はじめに ファイル「存在チェック」はなぜ大事か
業務システムでは、「このファイルがある前提」で処理を書いてしまうと、現場で簡単に事故が起きます。
たとえば「毎朝、前日の売上 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.Exists と if 文を書くと、コードが散らばって読みにくくなります。
そこで、「存在チェック専用の小さなメソッド」を用意しておくと、コードがかなりスッキリします。
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 だけでは防げないケースがある
少しレベルの高い話ですが、実務では「存在チェックをした直後に、ファイルが消される」こともあり得ます。
たとえば、別プロセスや別ユーザーが同じファイルを操作している場合です。
流れとしてはこうです。
File.Exists(path)でtrueが返る- その直後に、他のプロセスがファイルを削除する
- 自分のコードが
File.OpenRead(path)などを呼ぶ - 「ファイルが見つかりません」という例外が発生する
このように、「存在チェックをしたからといって、その後の操作が必ず成功するとは限らない」という点は、
実務ではとても重要な考え方です。
実務的な書き方のコツ
実務では、「存在チェック」と「実際の処理」の両方を意識して書きます。
- 事前に
File.Existsでチェックして、ユーザー向けの分かりやすいメッセージやログを出す - 実際にファイルを開くときは、念のため
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で守る
ここまで理解できれば、「ファイルがある前提で書いてしまって、現場で落ちる」という典型的なトラブルはかなり減らせます。

