本文介紹如何利用Linux系統(tǒng)下的標(biāo)準(zhǔn)C庫(kù)函數(shù)opendir、readdir和closedir實(shí)現(xiàn)目錄的遞歸遍歷。 雖然這些函數(shù)本身并不支持遞歸,但我們可以通過(guò)編寫(xiě)遞歸函數(shù)來(lái)完成此功能。
以下代碼示例演示了如何使用這些函數(shù)遞歸遍歷給定目錄:
#include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> void traverseDirectory(const char *path) { DIR *dir; struct dirent *entry; struct stat path_stat; // 打開(kāi)目錄 dir = opendir(path); if (dir == NULL) { perror("opendir"); return; } // 遍歷目錄條目 while ((entry = readdir(dir)) != NULL) { // 跳過(guò)"."和".." if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; // 構(gòu)建完整路徑 char fullPath[PATH_MAX]; snprintf(fullPath, sizeof(fullPath), "%s/%s", path, entry->d_name); // 獲取文件/目錄信息 if (stat(fullPath, &path_stat) == -1) { perror("stat"); continue; } // 遞歸處理子目錄 if (S_ISDIR(path_stat.st_mode)) { printf("目錄: %sn", fullPath); traverseDirectory(fullPath); } else { // 打印文件 printf("文件: %sn", fullPath); } } // 關(guān)閉目錄 closedir(dir); } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "用法: %s <目錄路徑>n", argv[0]); return EXIT_FAILURE; } traverseDirectory(argv[1]); return EXIT_SUCCESS; }
代碼說(shuō)明:
- 打開(kāi)目錄: opendir()函數(shù)打開(kāi)指定的目錄。
- 讀取目錄條目: readdir()函數(shù)逐個(gè)讀取目錄中的條目。
- 跳過(guò)特殊條目: 代碼跳過(guò)表示當(dāng)前目錄(“.”)和父目錄(“..”)的條目。
- 構(gòu)建完整路徑: snprintf()函數(shù)構(gòu)建每個(gè)條目的完整路徑。
- 獲取文件/目錄信息: stat()函數(shù)獲取文件或目錄的屬性信息,用于判斷是文件還是目錄。
- 遞歸處理: 如果條目是目錄(S_ISDIR()),則遞歸調(diào)用traverseDirectory()函數(shù)。
- 關(guān)閉目錄: closedir()函數(shù)關(guān)閉打開(kāi)的目錄。
編譯和運(yùn)行:
將代碼保存為例如recursive_traversal.c,然后使用以下命令編譯和運(yùn)行:
gcc -o recursive_traversal recursive_traversal.c ./recursive_traversal /path/to/your/directory
將/path/to/your/directory替換成你想要遍歷的目錄路徑。 程序會(huì)遞歸地列出該目錄及其所有子目錄下的文件和目錄。
這個(gè)改進(jìn)后的版本使用了更清晰的變量名和注釋?zhuān)?duì)代碼結(jié)構(gòu)進(jìn)行了微調(diào),使其更易于理解和維護(hù)。