在 Debian(或者说在 Linux 下用 C 语言)里,readdir() 本身不会展开符号链接,它只是读取目录项(dirent),符号链接在 readdir 看来和普通文件、目录一样,只是一个条目。
是否“处理符号链接”取决于你后续怎么用 stat / lstat。
readdir 返回什么#include <dirent.h>
DIR *dir = opendir(path);
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
// entry->d_name 是文件名
// entry->d_type 可能是:
// DT_REG 普通文件
// DT_DIR 目录
// DT_LNK 符号链接
// DT_UNKNOWN (某些文件系统不提供)
}
⚠️ 注意:
readdir() 不会区分符号链接指向的是文件还是目录d_type == DT_LNK 只说明“这是一个符号链接”stat vs lstatstat() —— 会跟随符号链接struct stat st;
stat(entry->d_name, &st);
S_ISDIR(st.st_mode) 可能为真(如果指向目录)lstat() —— 不跟随符号链接lstat(entry->d_name, &st);
S_ISLNK(st.st_mode)✅ 处理符号链接时,几乎总是先用 lstat()
lstat(name, &st);
if (S_ISLNK(st.st_mode)) {
printf("symbolic link: %s\n", name);
}
lstat(name, &st);
if (S_ISDIR(st.st_mode)) {
// 真正目录,可以递归
} else if (S_ISLNK(st.st_mode)) {
// 跳过符号链接目录
}
ls -L)stat(name, &st);
if (S_ISDIR(st.st_mode)) {
// 跟随后的目录
}
⚠️ 注意死循环风险(符号链接指向父目录)
#include <unistd.h>
char buf[PATH_MAX];
ssize_t len = readlink(name, buf, sizeof(buf)-1);
if (len != -1) {
buf[len] = '\0';
printf("points to: %s\n", buf);
}
readdir() 是 glibc 提供的 POSIX 接口d_type 在某些文件系统(如部分网络文件系统)可能是 DT_UNKNOWNd_type == DT_UNKNOWN,必须 lstat() 判断
readdir()不处理符号链接,lstat()决定是否把它当链接看,stat()会跟着它走。
如果你有具体场景(比如:递归删除、备份、Web 服务目录遍历),我可以给你更针对性的代码。