在 Ubuntu(Linux) 下,opendir() 是用来打开一个目录流的函数,常用于遍历目录。它是 POSIX 标准 API,在 <dirent.h> 中定义。
下面从 原理 + 示例 + 常见用法 给你讲清楚。
#include <dirent.h>
DIR *opendir(const char *name);
打开一个目录,返回一个 DIR* 目录流指针,供后续 readdir()、closedir() 使用。
DIR*NULL,并设置 errno#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
const char *path = "."; // 当前目录
DIR *dir = opendir(path);
if (dir == NULL) {
perror("opendir");
return EXIT_FAILURE;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
return 0;
}
gcc opendir_test.c -o opendir_test
./opendir_test
DIRDIR *dir;
目录流指针(类似 FILE*)
struct direntstruct dirent {
ino_t d_ino; // inode 号
off_t d_off;
unsigned short d_reclen;
unsigned char d_type; // 文件类型(DT_REG / DT_DIR)
char d_name[256]; // 文件名
};
✅ 常用字段
d_name:文件名d_type:文件类型(不是所有文件系统都支持). 和 ..while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
printf("%s\n", entry->d_name);
}
d_type(不一定可靠)if (entry->d_type == DT_REG)
printf("普通文件: %s\n", entry->d_name);
else if (entry->d_type == DT_DIR)
printf("目录: %s\n", entry->d_name);
⚠️ 某些文件系统(如 XFS、NFS)可能返回 DT_UNKNOWN
lstat()(最可靠 ✅)#include <sys/stat.h>
#include <string.h>
struct stat st;
char fullpath[512];
snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);
lstat(fullpath, &st);
if (S_ISREG(st.st_mode))
printf("文件: %s\n", entry->d_name);
else if (S_ISDIR(st.st_mode))
printf("目录: %s\n", entry->d_name);
opendir() → 打开目录
readdir() → 读取目录项
closedir() → 关闭目录
// ❌ 会导致文件描述符泄露
#include <dirent.h> // 必须
// ❌ 目录不能用 fopen
| 方法 | 说明 |
|---|---|
nftw() |
递归遍历目录 |
scandir() |
可排序、可过滤 |
readdir_r() |
已废弃(不推荐) |
在 Ubuntu 下,
opendir()+readdir()+closedir()是遍历目录的标准做法。
如果你需要:
可以直接告诉我,我可以给你完整代码。