[MFC/Win32API] ファイル・フォルダの存在チェック

[MFC] CFileFind

指定されたファイル名のファイルが存在する場合にtrueを返す。
ただし、ディレクトリのパスが与えられた場合、ディレクトリが存在してもfalseを返す。

ファイル単体の存在チェック

CFileFind find;
CString filePath = _T("C:\\foo.bar");

if( find.FindFile( filePath ) ){
 // ファイルが存在
}

フォルダ内ファイルの存在チェック

以下の例ではでファイル名の条件を指定。

CFileFind find;
CString dirPath = _T("C:\\foo\\bar");
dirPath += _T("*.txt"); // ファイルの条件

if( find.FindFile( dirPath ) ){
 // while( find.FindNextFile() ) // ※間違い※これだと処理出来るファイルが実際の数より1つ少ない

 bool flag;
 do{
  flag = find.FindNextFile(); 
  // *.txtファイルが存在したときの処理
 }while( flag ); // これなら対象ファイル全てが処理出来る
}

[Win32 API] Path関数

PathFileExists
指定されたパスにファイル、もしくはディレクトリが存在した場合にtrueを返す。
PathIsDirectory
指定されたパスがディレクトリならtrueを返す。

指定されたパスがファイルかディレクトリかで処理を切り分ける場合

CString path = _T("C:\\foo.bar");
if( ::PathFileExists( path ) && !::PathIsDirectory( path ) ){
 // 指定されたパスにファイルが存在、かつディレクトリでない
}else if( ::PathFileExists( path ) ){
 // 指定されたパスがディレクトリである
}

車輪の再発明

FindFirstFileを利用してもファイル・フォルダの存在確認にできるらしい。が、ルートディレクトリは検出できないっぽい。
上記のような関数を知らなかった為こんなものを作ってしまった。PathIsDirectory関数と(たぶんほぼ)等価なはず。

// 引数で与えられたフォルダのパスが存在するかを確認
// param: folderPath(参照渡し): フォルダのパス(最後の\記号はつけない)
// return: true: フォルダが存在 / false: フォルダが存在しない
bool isFolderExist( CString &folderPath ){
 HANDLE hFind;
 WIN32_FIND_DATA FindFileData;

 hFind = ::FindFirstFile( folderPath, &FindFileData );
 if( FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY ){
  // 引数のパスが正しい(フォルダが存在)
  return true;
 }

 // フォルダが存在しなかった場合、もしくはルートディレクトリを指定していた場合
 // ルートディレクトリならfolderPathの長さは2になるはず(C:)など
 if( folderPath.GetLength() == 2 ){
  TCHAR szBuff[125];	// 4*26 + 1
  ::GetLogicalDriveStrings( sizeof(szBuff), szBuff );
  for( int i = 0; i < 125 /* szBuffの配列長 */; i = i+4 ){
   if( szBuff[i] == folderPath.MakeUpper().GetAt(0) &&
    ':' == folderPath.GetAt(1) ){
    // 指定されたルートディレクトリのドライブレターが有効なドライブであった場合
    return true;
   }
  }
 }
 return false;
}

参考URL