【VC++】指定フォルダのファイル一覧をサブフォルダを含めて取得する
<機能>
(1)フォルダ選択ダイアログよりフォルダを選択します
(2)指定フォルダのファイル一覧をサブフォルダまで再帰的に検索します(※)
(3)ファイル一覧をテキストファイル(filelist.txt)に出力します
※フォルダ選択ダイアログについては過去記事 フォルダ選択ダイアログを表示する を参照
<動作検証&開発環境>
Visual Studio Community 2015
<イメージ>
実行ファイル格納フォルダ内にテキストファイル(filelist.txt)を作成し、ファイル一覧を出力します
<使い方>
(1)Win32コンソールアプリケーションでプロジェクトを作成
(2)[次へ]を押下し、アプリケーション設定画面の共通ヘッダーファイルを追加にて「MFC」にチェック
(3)構成プロパティ > 全般 > 文字セット で「マルチバイト文字セットを使用する」を指定
(4)ソースの追加
//定数定義とプロトタイプ宣言をヘッダファイルあるいはソースの先頭に追加してください
//定数定義
const int MAX_LEN = 2048;
//プロトタイプ宣言
BOOL SelectFolder(HWND hWnd, LPCTSTR lpDefFolder, LPTSTR lpSelectPath, UINT iFlg, CString ttl);
int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData);
void FindAllFile(CString dir, CStringArray &csalist);
// 唯一のアプリケーション オブジェクトです。
CWinApp theApp;
using namespace std;
int main()
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(nullptr);
if (hModule != nullptr)
{
// MFC を初期化して、エラーの場合は結果を印刷します。
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
//〜〜中略〜〜
}
else
{
char cDirSel[MAX_LEN] = {'¥0'};
CString csMsg;
CStringArray csalist;
int i;
FILE *fp;
//フォルダ選択で初期表示パスを指定
CString csDefaultFol = "C:¥¥";
//フォルダ選択ダイアログを表示する
//フォルダ選択ダイアログについては「http://pg-sample.sagami-ss.net/?eid=3」参照
if( SelectFolder(NULL, csDefaultFol, cDirSel, BIF_RETURNONLYFSDIRS, "XXXフォルダーを選択してください") )
{
//バッファをクリア
csalist.RemoveAll();
//再帰的にサブフォルダまで検索しファイル一覧を取得
FindAllFile(cDirSel, csalist);
}
else
{
//キャンセルされた
return 0;
}
//取得したファイル一覧を出力するファイルをオープン
int ierr = fopen_s(&fp, ".¥¥filelist.txt", "wb");
if (ierr != 0) {
AfxMessageBox("結果出力ファイルのオープン(書き込みモード)に失敗しました。処理を中止します。",MB_ICONSTOP);
return 0;
}
//ファイル一覧を出力する
csMsg.Format("ルートフォルダ [ %s ]¥r¥n", cDirSel);
fputs(csMsg, fp);
for (i = 0; i < csalist.GetSize(); i++)
{
fputs(csalist.GetAt(i) + "¥r¥n",fp);
}
csMsg.Format("検索ファイル数 [ %d ]¥r¥n",csalist.GetSize());
fputs(csMsg, fp);
int numclosed = _fcloseall();
AfxMessageBox("終了しました", MB_ICONINFORMATION);
}
}
else
{
//〜〜中略〜〜
}
return nRetCode;
}
/****************************************************************
指定フォルダを検索してファイル一覧作成(サブフォルダも検索する)
引数 検索するルートフォルダ
戻り値 ファイルリスト
****************************************************************/
void FindAllFile(CString dir, CStringArray &csalist)
{
CFileFind cFileFind;
CString strSearchFile = dir + ("¥¥*");
BOOL rtn;
CString cwk, cext;
//対象ファイルを検索
if (!cFileFind.FindFile(strSearchFile))
{
return;
}
else {
do
{
rtn = cFileFind.FindNextFile();
//".",".."でない場合に処理を行う
if (!cFileFind.IsDots()) {
cwk = cFileFind.GetFilePath();
//フォルダなら再帰的に検索を実行する
if (cFileFind.IsDirectory()) {
TRACE("検索中です... [ %s ]¥r¥n", dir);
//サブフォルダを検索する
FindAllFile(cwk, csalist);
}
else {
//拡張子を指定して検索する場合の実装例です
//例:txtファイルを抽出対象とする
//cext = cwk.Right(4);
//if ((cext.MakeUpper()) == ".TXT") {
// csalist.Add(cwk);
//}
//本サンプルでは全てのファイルを抽出対象とします
csalist.Add(cwk);
}
}
} while (rtn);
cFileFind.Close();
}
return;
}
/************************************************************
フォルダを指定(SelectFolder)
引数(IN):
hWnd ウインドウハンドル
lpDefFolder デフォルトで表示するフォルダパス
iFlg ダイアログオプション
ttl ダイアログのタイトルテキスト
引数(OUT):
lpSelectPath 選択されたフォルダパス
************************************************************/
BOOL SelectFolder(HWND hWnd, LPCTSTR lpDefFolder, LPTSTR lpSelectPath, UINT iFlg, CString ttl)
{
LPMALLOC pMalloc;
BOOL brtn = FALSE;
//IMallocインターフェイスへのポインタを取得
if (SUCCEEDED(SHGetMalloc(&pMalloc)))
{
BROWSEINFO brows;
ITEMIDLIST *pIDlist;
//BROWSEINFO構造体の初期化
memset(&brows, NULL, sizeof(brows));
//BROWSEINFO構造体に値をセット
brows.hwndOwner = hWnd;
brows.pszDisplayName = lpSelectPath;
brows.lpszTitle = ttl;
brows.lParam = (LPARAM)lpDefFolder;
brows.pidlRoot = NULL;
brows.ulFlags = iFlg;
brows.lpfn = &BrowseCallbackProc;
brows.iImage = (int)NULL;
//フォルダ選択ダイアログの表示
pIDlist = SHBrowseForFolder(&brows);
if (pIDlist == NULL)
//何も選択されなければデフォルトフォルダを返す
strcpy_s(lpSelectPath, MAX_LEN, lpDefFolder);
else {
//ITEMIDLIST からフルパスを得る
SHGetPathFromIDList(pIDlist, lpSelectPath);
brtn = TRUE;
//ITEMIDLIST の開放
pMalloc->Free(pIDlist);
}
pMalloc->Release();
}
return brtn;
}
int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
switch (uMsg)
{
case BFFM_INITIALIZED:
//初期化処理(初期表示フォルダ指定)
SendMessage(hWnd, BFFM_SETSELECTION, (WPARAM)TRUE, lpData);
break;
case BFFM_SELCHANGED:
//フォルダ選択ダイアログでフォルダが選択された時に処理が必要であればここに記載
TRACE("フォルダが選択されました?r?n");
break;
}
return 0;
}
よろしければポチッと押してください