// ファイル・フォルダ検索関数群 // (C)2002,2003 Yutaka Wada, AirparkLab // [注意] // 相対パスで読み込めるように便宜上ヘッダファイルにしている。 // インクルードするのは唯一のソースファイルのみとし、他はextern宣言して使用すること。 #ifndef __FILE_SEARCH_H__ #define __FILE_SEARCH_H__ #include "direct.h" // プロトタイプ宣言 BOOL FolderSearch( const char *pFolder ); BOOL FileSearch( const char *pFilename ); BOOL RecursiveSearchFile( const char *filename, const char *dir, char *fullpath ); BOOL GetFolderName( const char *pPath, char *pFolderName ); const char* GetElementName( const char *pPath ); BOOL RemoveTailSeparater( char *pPath ); // フォルダの検索 // pFolder で指定したフォルダが実在するかどうか調査し、 // 実在すれば TRUE 、無ければ FALSE を返す。 BOOL FolderSearch( const char *pFolder ) { BOOL ret; // カレントディレクトリの取得 char szCurrent[MAX_PATH]; GetCurrentDirectory( MAX_PATH, szCurrent ); // カレントディレクトリとして移動できるか調査 if( ::_chdir( pFolder ) == -1 ) ret = FALSE; else ret = TRUE; // カレントディレクトリの復帰 ::_chdir( szCurrent ); return( ret ); } // ファイルの検索 // pFilename で指定したファイルが実在するかどうか調査し、 // 実在すれば TRUE 、無ければ FALSE を返す。 BOOL FileSearch( const char *pFilename ) { HANDLE hnd; WIN32_FIND_DATA data; hnd = FindFirstFile( pFilename, &data ); if( hnd != INVALID_HANDLE_VALUE ){ FindClose( hnd ); return( TRUE ); } else return( FALSE ); } // サブフォルダも階層的にファイルを検索する関数(再帰) // filename を dir 以下から階層的に探し見つかれば TRUE, // 見つからなければ FALSE を返す。 // 見つかったファイルのフルパスは fullpath に保存する。 BOOL RecursiveSearchFile( const char *filename, const char *dir, char *fullpath ) { char path[MAX_PATH]; // 検索パス char folder[MAX_PATH]; // 検索フォルダ char recursive[MAX_PATH]; // 一つ下の検索パス HANDLE hnd; // 検索ハンドル WIN32_FIND_DATA data; // 発見ファイル情報を受ける変数 BOOL ret = FALSE; // 末尾の'\'処理(SJISコード対応) int len = strlen( dir ); if( len >= 2 && (unsigned char)dir[len-2] < 0x81 && dir[len-1] == '\\' ) sprintf( folder, "%s", dir ); else if( len >= 3 && (unsigned char)dir[len-3] >= 0x81 && dir[len-1] == '\\' ) sprintf( folder, "%s", dir ); else sprintf( folder, "%s\\", dir ); sprintf( path, "%s*.*", folder ); // 検索実行 hnd = FindFirstFile( path, &data ); if( hnd != INVALID_HANDLE_VALUE ){ do{ if( strcmp( ".", data.cFileName ) && strcmp( "..", data.cFileName ) ){ // ファイル(フォルダ)名の決定 sprintf( recursive, "%s%s", folder, data.cFileName ); // フォルダなら再帰的に検索を行う if( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ){ ret = RecursiveSearchFile( filename, recursive, fullpath ); if( ret == TRUE ) break; } // ファイルならファイル名を確認 else { // 同名であれば検索終了 if( strcmp( filename, data.cFileName ) == 0 ){ sprintf( fullpath, "%s%s", folder, filename ); ret = TRUE; break; } } } } while( FindNextFile( hnd, &data ) ); // 次のファイル(フォルダ)を検索 FindClose( hnd ); // ハンドルの後始末 } return( ret ); } // フルパスからフォルダ名のみを戻す // pPath で与えられたフルパスファイル名から、ファイル名と拡張子を除いた // フォルダ名のみを pFolderName に書き込む。pPath は変更されない。 // 存在するフォルダであれば TRUE を戻し、存在しないフォルダであれば FALSE を返す。 // 必ず末尾に'\'が付加されることに注意すること。 // 既にフォルダであれば末尾に'\'が付いた状態にして返す。 // pFolderName は十分な領域を確保すること。 BOOL GetFolderName( const char *pPath, char *pFolderName ) { // 既にフォルダの場合 if( FolderSearch( pPath ) == TRUE ){ strcpy( pFolderName, pPath ); // 末尾の'\'処理(SJISコード対応) size_t nLen = strlen( pFolderName ); if( nLen > 3 ){ RemoveTailSeparater( pFolderName ); size_t nLen = strlen( pFolderName ); pFolderName[nLen] = '\\'; pFolderName[nLen+1] = '\0'; } return( TRUE ); } // ファイル名の場合フルパスを分解 char szDrive[_MAX_DRIVE], szDir[_MAX_DIR], szFName[_MAX_FNAME], szExt[_MAX_EXT]; _splitpath( pPath, szDrive, szDir, szFName, szExt ); // フォルダ名のみ再構成 sprintf( pFolderName, "%s%s", szDrive, szDir ); // 実在するフォルダかどうかのチェックしてその結果を戻す BOOL bRet = FolderSearch( pFolderName ); return( bRet ); } // フルパスから最下位フォルダ名またはファイル名を戻す // pPath で与えられたフルパスファイル(またはフォルダ)名からファイル名のみ、 // または最下位フォルダ名へのアドレスを戻す。 // 戻り値のアドレスは引数である pPath 内部のアドレスであることに注意すること。 // また pPath の末尾が'\'である場合は pPath そのものが戻り値となる。 const char* GetElementName( const char *pPath ) { int nLen = strlen( pPath ); if( nLen <= 3 ) return( pPath ); // セパレータ文字'\'の検索(SJISコード対応) for( int i=nLen-1; i>=2; i-- ){ if( (unsigned char)pPath[i-1] < 0x81 && pPath[i] == '\\' ){ i++; break; } else if( (unsigned char)pPath[i-2] >= 0x81 && pPath[i] == '\\' ){ i++; break; } } if( i >= nLen || i <= 1 ) return( pPath ); else if( pPath[i] == '\0' ) return( pPath ); else return( &pPath[i] ); } // pPath で与えられたパス名の末尾が'\'であればNULL文字に変更し削除する。 // 与えられたアドレスの内容を変更するので注意すること。 // 存在するフォルダであれば TRUE を戻し、存在しないフォルダであれば FALSE を返す。 BOOL RemoveTailSeparater( char *pPath ) { int nLen = strlen( pPath ); // 末尾の'\'処理(SJISコード対応) if( nLen >= 2 && (unsigned char)pPath[nLen-2] < 0x81 && pPath[nLen-1] == '\\' ) pPath[nLen-1] = '\0'; else if( nLen >= 3 && (unsigned char)pPath[nLen-3] >= 0x81 && pPath[nLen-1] == '\\' ) pPath[nLen-1] = '\0'; // 実在するフォルダかどうかのチェックしてその結果を戻す BOOL bRet = FolderSearch( pPath ); return( bRet ); } #endif