温馨提示×

linux readdir怎样获取属性

小樊
45
2026-09-14 19:10:39
栏目: 智能运维

在 Linux 下,readdir 本身只能获取目录项(文件名、inode 号等),并不能直接获取文件属性(如大小、权限、修改时间等)。要获取文件属性,需要配合 stat / lstat 系列函数使用。

下面分情况说明。


一、readdir 能拿到什么

#include <dirent.h>

struct dirent {
    ino_t          d_ino;     // inode 号
    off_t          d_off;     // 偏移
    unsigned short d_revel;   // 记录长度
    unsigned char  d_type;    // 文件类型(部分系统支持)
    char           d_name[];  // 文件名
};

示例:

DIR *dir = opendir(".");
struct dirent *entry;

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

⚠️ readdir 不包含:

  • 文件大小
  • 权限
  • 所有者
  • 修改时间

二、获取文件属性:使用 stat

1️⃣ 基本用法

#include <sys/stat.h>
#include <unistd.h>

struct stat st;
if (stat(entry->d_name, &st) == 0) {
    printf("size: %ld\n", st.st_size);
    printf("mode: %o\n", st.st_mode);
}

⚠️ 注意:
entry->d_name 只是文件名,不是完整路径
正确做法应拼接路径


2️⃣ 正确拼接路径(推荐)

char path[1024];
snprintf(path, sizeof(path), "%s/%s", dir_path, entry->d_name);

struct stat st;
if (stat(path, &st) == 0) {
    // 使用 st
}

三、readdir + stat 完整示例

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

int main(int argc, char *argv[]) {
    const char *dir_path = ".";
    DIR *dir = opendir(dir_path);
    if (!dir) return 1;

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (strcmp(entry->d_name, ".") == 0 ||
            strcmp(entry->d_name, "..") == 0)
            continue;

        char path[1024];
        snprintf(path, sizeof(path), "%s/%s", dir_path, entry->d_name);

        struct stat st;
        if (stat(path, &st) == 0) {
            printf("%s: size=%ld, mode=%o\n",
                   entry->d_name, st.st_size, st.st_mode);
        }
    }

    closedir(dir);
    return 0;
}

四、readdir 的 d_type(轻量判断)

有些文件系统支持 d_type:

if (entry->d_type == DT_REG)  // 普通文件
if (entry->d_type == DT_DIR)  // 目录

⚠️ 不是所有文件系统都保证有效(如某些网络文件系统)


五、进阶:readdir + fstatat(推荐现代写法)

避免路径拼接问题:

#include <fcntl.h>
#include <sys/stat.h>

int dfd = dirfd(dir);
fstatat(dfd, entry->d_name, &st, 0);

优点:

  • 更安全
  • 性能更好
  • 支持相对路径

六、总结

需求 方法
遍历目录 opendir + readdir
获取文件属性 stat / lstat / fstatat
只判断类型 d_type

如果你需要:

  • 递归遍历
  • 符号链接处理
  • 类似 ls -l 的输出

可以继续问我。

0 踩