首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC++ 遞歸遍歷目錄樹查找文件實戰

     編輯:關於VC++

應用場景

在 SDI 專案中結合 CFileDialog 選擇起始目錄,利用 CFileFind 遞歸掃描,可靈活實現自定義條件的文件搜尋(如:唯讀、大小範圍、擴展名等),並將結果輸出至 VC++ 輸出視窗。

完整實現代碼

#include <direct.h>  // _getcwd, _chdir

void f0() {
    char x[256], y[256];
    CFileDialog fd(TRUE); // "File Open" 對話框
    _getcwd(x, 256);      // 保存當前工作目錄
    
    if (fd.DoModal() == IDOK) {
        _getcwd(y, 256);  // 取得用戶選擇的目錄 (c:\windows)
        f1(y);            // 開始遞歸搜尋
    }
    _chdir(x);            // 還原工作目錄
}

void f1(CString x) {
    BOOL b; CFileFind f;  // 局部變數支援遞歸
    _chdir(x);            // 切換至目標目錄
    b = f.FindFile(_T("*.*")); // 查找所有文件
    
    while (b) {
        b = f.FindNextFile();
        if (f.IsDirectory()) {
            if (!f.IsDots()) { // 排除 "." 和 ".."
                f1(f.GetFilePath()); // 遞歸進入子目錄
            }
        } else if (f.IsReadOnly() && f.GetLength() < 500) {
            afxDump << "\n" << f.GetFilePath(); // 輸出符合條件文件
        }
    }
}

關鍵技術點解析

  1. 工作目錄管理:_getcwd/_chdir 確保遞歸過程中相對路徑正確
  2. 局部變數遞歸:CFileFind f 必須宣告為函數局部變數,否則遞歸層級會共用同一物件導致狀態混亂
  3. 目錄過濾:IsDots() 排除當前/父目錄,防止無限遞歸
  4. 條件組合:IsReadOnly() && GetLength() < 500 示範多條件邏輯
  5. 輸出導向:afxDump 直接輸出至 VC++「輸出」視窗,便於除錯

記憶體洩漏驗證

經 CMemoryState 檢測,本代碼無記憶體洩漏。關鍵在於:

  • CFileFind 析構時自動關閉搜尋句柄
  • 無動態記憶體分配
  • 遞歸深度受限於目錄層級,系統棧可承受

擴展應用建議

  • 進度回報:添加回呼函數指標,定期通知 UI 更新進度條
  • 多執行緒:將 f1 放入工作執行緒,避免 UI 凍結
  • 結果收集:改寫為填充 CStringArray 或 std::vector<CString> 供後續處理
  • 過濾器抽象:定義 virtual bool Match(const CFileFind&) 介面,支援插件式條件

常見坑點提醒

問題原因修正
遞歸導致棧溢位目錄層級過深(>1000層)改用非遞歸棧/隊列實現 BFS/DFS
網路路徑失敗_chdir 不支援 UNC 路徑使用完整路徑 CFileFind::FindFile(fullPath) 避免切換目錄
權限拒絕崩潰無權限讀取系統目錄包裹 FindFile/FindNextFile 於 try-catch 或檢查返回值

總結

本方案以 CFileDialog + CFileFind + 遞歸函數的經典組合,實現靈活可擴展的目錄樹搜尋。代碼精簡、無洩漏、易於理解與修改,是 MFC 文件系統操作的優秀教學範例與實用基礎組件。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved