温馨提示×

debian readdir如何编写

小樊
44
2026-07-13 19:12:29
栏目: 智能运维

在 Debian(以及大多数 Linux 系统)上,readdirPOSIX 标准目录读取函数,用于遍历目录内容。下面我按从简单到完整的方式给你说明,并给出可直接编译的示例。


一、readdir 是什么?

readdir 用来读取目录中的文件/子目录项

相关函数:

#include <dirent.h>

DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);
int closedir(DIR *dirp);

二、最简单的 readdir 示例

示例:列出当前目录下的所有文件

#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;
}

编译(Debian):

gcc readdir_example.c -o readdir_example
./readdir_example

三、struct dirent 常用字段

struct dirent {
    ino_t          d_ino;       // inode 号
    off_t          d_off;
    unsigned short d_reclen;
    unsigned char  d_type;      // 文件类型(不一定所有文件系统都支持)
    char           d_name[256]; // 文件名
};

d_type 常见值

含义
DT_REG 普通文件
DT_DIR 目录
DT_LNK 符号链接
DT_BLK 块设备
DT_CHR 字符设备
DT_FIFO 管道
DT_SOCK socket

⚠️ 注意d_type 在某些文件系统(如 XFS、NFS)上可能是 DT_UNKNOWN


四、区分目录和普通文件(推荐方式)

使用 lstat(更可靠)

#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
❌ 使用 readdird_name 不是绝对路径
❌ 在多线程中使用 readdir(应使用 readdir_rreaddir_r 已废弃,现代系统用 readdir + 锁)


八、Debian 手册页

man readdir
man opendir
man closedir
man dirent

如果你需要的是:

  • 内核模块里的 readdir
  • 系统调用 (getdents)
  • shell / Python / Go 实现
  • 高性能目录遍历

告诉我你的具体使用场景,我可以进一步细化。

0