
opendir 函数本身无法实现递归目录遍历,需要结合 readdir、closedir 和 stat (或 lstat 避免符号链接问题) 函数,并使用递归调用来实现。以下是一个改进的 C 语言示例,它能够更稳健地处理目录遍历,包括符号链接:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <limits.h> // for PATH_MAX
void list_directory_contents(const char *path) {
DIR *dir;
struct dirent *entry;
struct stat path_stat;
char full_path[PATH_MAX];
dir = opendir(path);
if (!dir) {
perror("opendir");
return;
}
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
// 使用 snprintf 避免缓冲区溢出
if (snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name) >= sizeof(full_path)) {
fprintf(stderr, "Path too long: %s/%s\n", path, entry->d_name);
continue;
}
if (lstat(full_path, &path_stat) == -1) { // 使用 lstat 处理符号链接
perror("lstat");
continue;
}
if (S_ISDIR(path_stat.st_mode)) {
list_directory_contents(full_path);
} else if (S_ISREG(path_stat.st_mode)) { // 只打印常规文件
printf("%s\n", full_path);
} else if (S_ISLNK(path_stat.st_mode)) {
printf("Symbolic link: %s\n", full_path); // 处理符号链接
} else {
printf("Other file type: %s\n", full_path); // 处理其他文件类型
}
}
closedir(dir);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <directory>\n", argv[0]);
return EXIT_FAILURE;
}
list_directory_contents(argv[1]);
return EXIT_SUCCESS;
}此版本改进之处:
opendir 和 lstat 的错误检查。snprintf 来防止潜在的缓冲区溢出,避免路径过长导致程序崩溃。lstat 代替 stat,可以正确处理符号链接,避免无限递归。这个程序仍然假设 PATH_MAX 是定义的,在某些系统中可能需要包含额外的头文件或使用其他方法来获取最大路径长度。 记住编译时需要链接 -lm (如果你的系统需要)。 例如:gcc your_file.c -o your_program -lm
以上就是如何用copendir实现递归目录遍历的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号