温馨提示×

linux readdir怎样判断

小樊
49
2026-10-08 13:17:40
栏目: 智能运维

在 Linux 下使用 readdir(通常指 readdir() 或 readdir_r(),来自 <dirent.h>)时,**“怎样判断”**一般指的是几类情况:判断是否读到了目录项、判断文件类型、判断是否读完、判断是否出错。下面系统说明。


1. 基本用法(readdir)

#include <dirent.h>
#include <stdio.h>

DIR *dir = opendir("/path");
if (!dir) {
    perror("opendir");
    return -1;
}

struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
    printf("%s\n", entry->d_name);
}

closedir(dir);

2. 怎样判断“是否读到内容 / 是否结束”

✅ 判断是否读到目录项

if (entry != NULL) {
    // 读到一个目录项
}

✅ 判断是否读完

while ((entry = readdir(dir)) != NULL) {
    // 还有内容
}
// 跳出循环 = 读完了

readdir 返回 NULL 有两种可能:

  • 正常读完
  • 出错(需配合 errno)

3. 怎样判断“是否出错”

errno = 0;
entry = readdir(dir);
if (entry == NULL) {
    if (errno != 0) {
        perror("readdir");
    } else {
        // 正常结束
    }
}

4. 怎样判断“文件类型”(重点)

struct dirent 中有:

struct dirent {
    ino_t          d_ino;
    off_t          d_off;
    unsigned short d_reclen;
    unsigned char  d_type;
    char           d_name[256];
};

用 d_type 判断(推荐,高效)

switch (entry->d_type) {
    case DT_REG:  printf("普通文件\n"); break;
    case DT_DIR:  printf("目录\n"); break;
    case DT_LNK:  printf("符号链接\n"); break;
    case DT_CHR:  printf("字符设备\n"); break;
    case DT_BLK:  printf("块设备\n"); break;
    case DT_FIFO: printf("管道\n"); break;
    case DT_SOCK: printf("socket\n"); break;
    case DT_UNKNOWN: printf("未知类型\n"); break;
}

⚠️ 注意:

  • 某些文件系统(如部分网络文件系统)d_type 可能是 DT_UNKNOWN

5. 精确判断文件类型(stat)

若 d_type == DT_UNKNOWN,用 stat:

#include <sys/stat.h>

struct stat st;
char path[512];
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);

if (stat(path, &st) == 0) {
    if (S_ISREG(st.st_mode))  printf("普通文件\n");
    if (S_ISDIR(st.st_mode))  printf("目录\n");
    if (S_ISLNK(st.st_mode))  printf("链接\n");
}

6. 常见判断场景示例

跳过 . 和 ..

if (strcmp(entry->d_name, ".") == 0 ||
    strcmp(entry->d_name, "..") == 0)
    continue;

判断是否普通文件

if (entry->d_type == DT_REG)

判断是否目录

if (entry->d_type == DT_DIR)

7. 线程安全版本(readdir_r,已不推荐)

struct dirent entry;
struct dirent *result;
readdir_r(dir, &entry, &result);
if (result == NULL) {
    // 结束或出错
}

⚠️ 现代 glibc 推荐直接用 readdir


总结一句话

readdir 判断逻辑:

  • NULL → 结束或出错(看 errno)
  • d_type → 快速判断文件类型
  • stat → 精确判断
  • 跳过 . / .. 是常规操作

如果你有具体场景(比如递归遍历、过滤文件、C++/Rust 实现),可以继续问。

0 踩