在 Linux 下,readdir 本身只能获取目录项(文件名、inode 号等),并不能直接获取文件属性(如大小、权限、修改时间等)。要获取文件属性,需要配合 stat / lstat 系列函数使用。
下面分情况说明。
#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 不包含:
#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 只是文件名,不是完整路径
正确做法应拼接路径
char path[1024];
snprintf(path, sizeof(path), "%s/%s", dir_path, entry->d_name);
struct stat st;
if (stat(path, &st) == 0) {
// 使用 st
}
#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;
}
有些文件系统支持 d_type:
if (entry->d_type == DT_REG) // 普通文件
if (entry->d_type == DT_DIR) // 目录
⚠️ 不是所有文件系统都保证有效(如某些网络文件系统)
避免路径拼接问题:
#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 的输出可以继续问我。