在 Debian(以及大多数 Linux 系统)上,readdir 是 POSIX 标准目录读取函数,用于遍历目录内容。下面我按从简单到完整的方式给你说明,并给出可直接编译的示例。
readdir 用来读取目录中的文件/子目录项。
相关函数:
#include <dirent.h>
DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);
int closedir(DIR *dirp);
#include <stdio.h>
#include <dirent.h>
int main(void)
{
DIR *dir;
struct dirent *entry;
dir = opendir(".");
if (dir == NULL) {
perror("opendir");
return 1;
}
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
return 0;
}
gcc readdir_example.c -o readdir_example
./readdir_example
struct dirent {
ino_t d_ino; // inode 号
off_t d_off;
unsigned short d_reclen;
unsigned char d_type; // 文件类型(不一定所有文件系统都支持)
char d_name[256]; // 文件名
};
| 值 | 含义 |
|---|---|
| DT_REG | 普通文件 |
| DT_DIR | 目录 |
| DT_LNK | 符号链接 |
| DT_BLK | 块设备 |
| DT_CHR | 字符设备 |
| DT_FIFO | 管道 |
| DT_SOCK | socket |
⚠️ 注意:d_type 在某些文件系统(如 XFS、NFS)上可能是 DT_UNKNOWN。
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
int main(void)
{
DIR *dir;
struct dirent *entry;
struct stat st;
char path[512];
dir = opendir(".");
if (!dir) {
perror("opendir");
return 1;
}
while ((entry = readdir(dir)) != NULL) {
snprintf(path, sizeof(path), "./%s", entry->d_name);
if (lstat(path, &st) == -1)
continue;
if (S_ISDIR(st.st_mode))
printf("[DIR] %s\n", entry->d_name);
else
printf("[FILE] %s\n", entry->d_name);
}
closedir(dir);
return 0;
}
. 和 ..if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
void list_dir(const char *path)
{
DIR *dir = opendir(path);
struct dirent *entry;
char newpath[512];
if (!dir) return;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
printf("%s/%s\n", path, entry->d_name);
if (entry->d_type == DT_DIR) {
snprintf(newpath, sizeof(newpath), "%s/%s", path, entry->d_name);
list_dir(newpath);
}
}
closedir(dir);
}
❌ 忘记 closedir
❌ 使用 readdir 后 d_name 不是绝对路径
❌ 在多线程中使用 readdir(应使用 readdir_r 或 readdir_r 已废弃,现代系统用 readdir + 锁)
man readdir
man opendir
man closedir
man dirent
如果你需要的是:
告诉我你的具体使用场景,我可以进一步细化。