Windows API 提供完整的檔案系統操作能力,本文涵蓋當前目錄控制、模組路徑取得、單層遍歷、遞迴目錄樹三大核心場景,代碼均可直接編譯執行。
CHAR cur[MAX_PATH];
DWORD len = GetCurrentDirectory(MAX_PATH, cur); // 取得
SetCurrentDirectory("C:\\"); // 設定
CreateDirectory("Current_dir", NULL); // 建立子目錄
CHAR path[MAX_PATH];
GetModuleFileName(NULL, path, MAX_PATH); // 本程式路徑
HMODULE hMod = LoadLibrary("kernel32.dll");
GetModuleFileName(hMod, path, MAX_PATH); // 指定 DLL 路徑
使用 FindFirstFile / FindNextFile 搭配 WIN32_FIND_DATA。
DWORD EnumerateDirectory(LPCSTR szPath) {
WIN32_FIND_DATA fd;
CHAR searchPath[MAX_PATH];
wsprintf(searchPath, "%s\\*", szPath);
HANDLE hFind = FindFirstFile(searchPath, &fd);
if (hFind == INVALID_HANDLE_VALUE) return 1;
do {
printf("%s\t", fd.cFileName);
if (fd.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) printf("<加密>");
if (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) printf("<隱藏>");
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) printf("<DIR>");
printf("\n");
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
return 0;
}
遇到子目錄時遞迴呼叫自身,需過濾 . 與 .. 避免無限循環。
DWORD g_total = 0;
DWORD ListAllRecursive(LPCSTR szPath) {
WIN32_FIND_DATA fd;
CHAR search[MAX_PATH], full[MAX_PATH];
wsprintf(search, "%s\\*", szPath);
HANDLE hFind = FindFirstFile(search, &fd);
if (hFind == INVALID_HANDLE_VALUE) return 1;
do {
if (!lstrcmp(fd.cFileName, ".") || !lstrcmp(fd.cFileName, "..")) continue;
wsprintf(full, "%s\\%s", szPath, fd.cFileName);
printf("\n%u\t%s\t", ++g_total, full);
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
printf("<DIR>");
ListAllRecursive(full);
}
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
return 0;
}
int main(int argc, char* argv[]) {
CHAR startPath[MAX_PATH];
if (argc == 2) lstrcpy(startPath, argv[1]);
else GetCurrentDirectory(MAX_PATH, startPath);
ListAllRecursive(startPath);
return 0;
}
| 旗標 | 含義 |
|---|---|
FILE_ATTRIBUTE_DIRECTORY | 目錄 |
FILE_ATTRIBUTE_HIDDEN | 隱藏 |
FILE_ATTRIBUTE_SYSTEM | 系統檔案 |
FILE_ATTRIBUTE_READONLY | 唯讀 |
FILE_ATTRIBUTE_ARCHIVE | 封存屬性 |
FILE_ATTRIBUTE_ENCRYPTED | EFS 加密 |
FILE_ATTRIBUTE_COMPRESSED | 壓縮 |
FILE_ATTRIBUTE_REPARSE_POINT | 連結點/符號連結 |
INVALID_HANDLE_VALUE 並呼叫 GetLastErrorMAX_PATH (260),長路徑需加 \\\\?\\ 前綴std::filesystem::recursive_directory_iterator