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

Qt 遞歸遍歷目錄:使用 QDir::entryInfoList 實現深度優先全文件訪問

     編輯:關於C語言

需求

遞歸訪問指定目錄下的 所有文件(包含子目錄、孫目錄等任意深度),對每個文件執行自定義操作(如收集路徑、計算哈希、批量重命名等)。

核心類與關鍵函數

類/函數用途
QDir::entryInfoList()返回 QFileInfoList(即 QList<QFileInfo>),包含目錄下所有條目信息
QFileInfo::isDir()判斷是否為目錄(含符號鏈接指向目錄)
QFileInfo::filePath()獲取絕對/相對完整路徑
QFileInfo::fileName()僅獲取文件名(不含路徑)
QDir::setFilter()設置過濾器:QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot
QDir::setSorting()設置排序:QDir::DirsFirst 目錄優先,便於深度優先遞歸

完整遞歸實現(含去重與效率優化)

void findFile(const QString &path) {
    QDir dir(path);
    if (!dir.exists()) return;

    dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
    dir.setSorting(QDir::DirsFirst);

    QFileInfoList list = dir.entryInfoList();      // 目錄+文件混合列表
    QStringList fileNames = dir.entryList(QDir::Files | QDir::NoDotAndDotDot); // 純文件名列表

    int i = 0;
    do {
        QFileInfo fileInfo = list.at(i);
        // 跳過 "." ".." (雖然過濾器已排除,雙重保險)
        if (fileInfo.fileName() == "." || fileInfo.fileName() == "..") {
            ++i; continue;
        }

        if (fileInfo.isDir()) {
            // 深度優先遞歸進入子目錄
            findFile(fileInfo.filePath());
        } else {
            // 當前目錄下的所有文件集中處理
            for (int m = 0; m < fileNames.size(); ++m) {
                QString fileName = fileNames.at(m);
                // ---- 在此處編寫具體文件操作邏輯 ----
                // 例如:qDebug() << fileInfo.absoluteFilePath();
            }
            break; // 關鍵:文件已處理完畢,退出 while 迴圈返回上層
        }
        ++i;
    } while (i < list.size());
}

關鍵細節解析

  1. 雙列表配合:list 保持「目錄在前、文件在後」順序,用於遞歸導航;fileNames 僅含文件名,用於批量業務處理。
  2. break 的必要性:進入 else 分支說明已處理完當前目錄所有文件,若不 break,外層 while 會繼續迭代剩餘 list 項(實際上已無文件),導致同一文件被重複處理多次,造成資源浪費與邏輯錯誤。
  3. 符號鏈接處理:isDir() 對指向目錄的符號鏈接返回 true,遞歸時可能進入循環鏈接,生產環境建議加入已訪問路徑集合(QSet<QString>)去重。

常見錯誤對比

網上流傳版本常漏掉 break,導致文件重複訪問。本文給出的版本經實測修正,歡迎對比驗證。

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