核心 API
FindFirstFile / FindNextFile / FindClose:列舉目錄項目。
WIN32_FIND_DATA:取得檔案屬性(dwFileAttributes 判斷目錄)。
GetCurrentDirectory:取得當前工作目錄。
遞迴函數 ListAllFileInDirectory
DWORD ListAllFileInDirectory(LPSTR szPath) {
CHAR szFilePath[MAX_PATH], szFullPath[MAX_PATH];
WIN32_FIND_DATA findData;
HANDLE hFind;
wsprintf(szFilePath, "%s\\*", szPath); // 通配符列舉所有
hFind = FindFirstFile(szFilePath, &findData);
if (hFind == INVALID_HANDLE_VALUE) return 1;
do {
if (lstrcmp(findData.cFileName, ".") == 0 || lstrcmp(findData.cFileName, "..") == 0)
continue; // 跳過當前/父目錄
wsprintf(szFullPath, "%s\\%s", szPath, findData.cFileName);
dwTotalFileNum++;
printf("\n%d\t%s\t", dwTotalFileNum, szFullPath);
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
printf("<DIR>");
ListAllFileInDirectory(szFullPath); // 遞迴進入子目錄
}
} while (FindNextFile(hFind, &findData));
FindClose(hFind);
return 0;
}
主程式入口
int main(int argc, PCHAR argv[]) {
CHAR szCurrentPath[MAX_PATH];
if (argc == 2)
ListAllFileInDirectory(argv[1]);
else {
GetCurrentDirectory(MAX_PATH, szCurrentPath);
ListAllFileInDirectory(szCurrentPath);
}
return 0;
}
關鍵實作細節
- 使用
MAX_PATH (260) 固定緩衝區,深層目錄可能溢位,生產環境建議動態分配或使用 \\?\ 前綴支援長路徑。
- 遞迴深度受限於堆疊大小,極深目錄樹可能堆疊溢位,可改用顯式堆疊(
std::stack)實作迭代版本。
- 錯誤處理:
FindFirstFile 失敗時呼叫 GetLastError() 取得錯誤碼。
- Unicode 支援:正式專案應使用
W 版 API(FindFirstFileW)搭配 wchar_t。
跨平台替代方案
- C++17
std::filesystem::recursive_directory_iterator(現代、標準、跨平台)。
- Boost.Filesystem(C++17 前)。
- POSIX
opendir/readdir/stat(Linux/Unix)。