遞歸訪問指定目錄下的 所有文件(包含子目錄、孫目錄等任意深度),對每個文件執行自定義操作(如收集路徑、計算哈希、批量重命名等)。
| 類/函數 | 用途 |
|---|---|
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());
}
list 保持「目錄在前、文件在後」順序,用於遞歸導航;fileNames 僅含文件名,用於批量業務處理。else 分支說明已處理完當前目錄所有文件,若不 break,外層 while 會繼續迭代剩餘 list 項(實際上已無文件),導致同一文件被重複處理多次,造成資源浪費與邏輯錯誤。isDir() 對指向目錄的符號鏈接返回 true,遞歸時可能進入循環鏈接,生產環境建議加入已訪問路徑集合(QSet<QString>)去重。網上流傳版本常漏掉 break,導致文件重複訪問。本文給出的版本經實測修正,歡迎對比驗證。