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

Windows 檔案與目錄管理完整指南:路徑、遍歷與遞迴樹

     編輯:關於C語言

前言

Windows API 提供完整的檔案系統操作能力,本文涵蓋當前目錄控制、模組路徑取得、單層遍歷、遞迴目錄樹三大核心場景,代碼均可直接編譯執行。

一、目錄與模組路徑操作

1. 取得/設定當前目錄

CHAR cur[MAX_PATH];
DWORD len = GetCurrentDirectory(MAX_PATH, cur); // 取得
SetCurrentDirectory("C:\\");                    // 設定
CreateDirectory("Current_dir", NULL);           // 建立子目錄

2. 取得模組完整路徑

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_ENCRYPTEDEFS 加密
FILE_ATTRIBUTE_COMPRESSED壓縮
FILE_ATTRIBUTE_REPARSE_POINT連結點/符號連結

六、最佳實務

  • 永遠檢查 INVALID_HANDLE_VALUE 並呼叫 GetLastError
  • 路徑緩衝區使用 MAX_PATH (260),長路徑需加 \\\\?\\ 前綴
  • 遞迴深度極大時考慮改用堆疊模擬避免堆疊溢位
  • C++17 專案優先使用 std::filesystem::recursive_directory_iterator
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved