めもてう

忘れっぽいTIPs、HowToのメモ帳です。

【C#】パス(文字列)が欲しいファイル形式(拡張子)か判定する

ファイルを扱うアプリを作っていると、指定されたファイルがアプリに対応した形式かどうかの判定は避けて通れません。
そこで、指定したファイルパスが対応しているファイル形式(拡張子)かどうか判定する関数を作っておくとなにかと便利です。

目標

string で受け取ったフルパスが指定した形式(拡張子)のファイルパスか判定する。

仕様

  1. ファイルパス(string)と判定する拡張子(string)を受け取って真偽(bool)を返す。
  2. ファイルパスまたは拡張子が空文字列などの場合は例外ではなく false を返す。
bool hasExtension(string path, string extension) {
  if(string.IsNullOrEmpty(path) || string.IsNullOrEmpty(extension)) { return false; }

  // 判定処理

  return true;
}

実装1 - string だけでがんばる

引数で受け取るファイルパスは文字列なので string の文字列操作関数でなんとかします。

bool hasExtension(string path, string extension) {
  // 引数のどちらかが空文字列もしくは null だった場合 false を返す
  if(string.IsNullOrEmpty(path) || string.IsNullOrEmpty(extension)) { return false; }

  // 拡張子の指定は '.' 有りが都合がいいので、無い場合は先頭に付加
  string ext = extension;
  if(ext[0] != '.') {
    ext = "." + ext;
  }

  // 指定されたパスから拡張子の位置を取得
  // パスに拡張子が含まれていなければ false を返す
  int index = path.LastIndexOf('.');
  if (index < 0) { return false; }

  // パスから拡張子部分を切り出す
  string pathExt = path.Substring(index);

  // 指定拡張子と切り出した拡張子の文字数が合わない
  // つまりパスの末尾ではなく途中に指定拡張子と同じ文字列がある場合は false を返す
  // 例)path = @"C:\Directory\File.jpg.gif" extension = ".jpg"
  // 例)path = @"C:\Directory.jpg\File" extension = ".jpg"
  if(ext.Length != pathExt.Length) { return false; }

  // 最後に大文字小文字を無視して比較をする
  if (string.Compare(pathExt, ext, true) != 0) { return false; }

  return true;
}

この実装でパスが特定のファイル形式かどうかを判定できます。

問題点

この実装では C:\Directory.jpg という「ディレクトリ」も true を返してしまいますし、指定したパスのファイルが存在するかどうかも判定できません。
まぁ、パスを評価するという意味では関数の外で存在の有無なんかは判定するのが正しい気がしますが。ただ、「ファイル」のパスということを考えると存在の有無も判定出来たほうが便利かなぁとも思います。
どちらにせよこの問題点は string だけではどうしようもありません。その場合は system.IO にある Fileクラスを使います。

実装2 - ファイルが存在するかも判定

bool hasExtension(string path, string extension, bool checkExistence = true) {
  // 引数のどちらかが空文字列もしくは null だった場合 false を返す
  if(string.IsNullOrEmpty(path) || string.IsNullOrEmpty(extension)) { return false; }

  // ファイルの有無をチェック
  // ファイルが存在しなければ false を返す
  if(checkExistence && !File.Exists(path)){ return false; }

  // 拡張子の指定は '.' 有りが都合がいいので、無い場合は先頭に付加
  string ext = extension;
  /*
  以下、実装1と同じ
  */

たった一行の追加です。
実装1の問題点で触れているファイルの有無判定は関数の外でするということを考慮して引数に有無判定をするかしないかのフラグを追加しています。
File.Exists 関数は指定したパスのファイルが存在した場合 true を返します。ファイルが存在しない場合や指定したパスがディレクトリを指している場合は false を返します。

まとめ

正規表現使えば短くできるんじゃね?とか File クラス使うんなら Path クラス使えばよくね?とか詰められるところはあるとは思いますが、ひとまずパスが指定したファイル形式(拡張子)であるか判定することができました。
この記事を書いていて File クラスに拡張子判定があってもいいのになぁと思いました(あったらゴメンなさい)。

ここで記載されているソースコードを使用する場合は自己責任でお願いします。

プライバシーポリシー (Privacy policy)