如何从<dirent.h>的DIR*指针中获取完整文件路径(Linux适用)
Linux下从DIR*指针获取对应目录绝对路径的方法
首先POSIX标准的<dirent.h>没有提供直接从DIR*类型指针读取对应目录路径的接口,你可以根据使用场景选择以下两种方案:
方案1:自行留存打开路径(推荐,跨平台)
如果你是通过opendir()自行打开的目录,最稳妥、兼容性最高的方式是在调用opendir()时就把传入的路径留存一份,后续需要时直接使用即可。这种方式不依赖平台特性,所有POSIX兼容系统都能使用。
方案2:借助Linux /proc文件系统读取(无需留存原路径,Linux专属)
如果DIR*指针是其他模块传入,无法直接拿到原打开路径,可以借助Linux特有的/proc文件系统实现,步骤如下:
- 调用
dirfd(DIR *dirp)函数获取DIR*指针对应的文件描述符,该函数属于POSIX标准接口,头文件同样为<dirent.h> - 构造对应fd的proc路径,格式为
/proc/self/fd/<fd数值>,该路径是指向进程打开文件的软链接 - 调用
realpath()或者readlink()读取上述软链接的内容,即可得到该目录对应的绝对路径
代码示例
#include <stdio.h> #include <dirent.h> #include <limits.h> #include <unistd.h> #include <stdlib.h> /** * 从DIR*指针获取对应目录的绝对路径 * @param dirp 已打开的DIR指针 * @param buf 存储路径的缓冲区,建议大小为PATH_MAX * @param buf_size 缓冲区大小 * @return 成功返回buf指针,失败返回NULL */ char* get_dir_abs_path(DIR* dirp, char* buf, size_t buf_size) { int dir_fd = dirfd(dirp); if (dir_fd < 0) { perror("获取目录fd失败"); return NULL; } char proc_link_path[32]; snprintf(proc_link_path, sizeof(proc_link_path), "/proc/self/fd/%d", dir_fd); return realpath(proc_link_path, buf); } // 使用示例 int main() { DIR* test_dir = opendir("../test"); if (!test_dir) { perror("打开目录失败"); return 1; } char path_buf[PATH_MAX]; if (get_dir_abs_path(test_dir, path_buf, sizeof(path_buf))) { printf("目录绝对路径:%s\n", path_buf); } closedir(test_dir); return 0; }
注意事项
- 该方案仅支持Linux系统,其他类Unix系统如果没有实现/proc文件系统则无法使用
- 如果目录打开后被移动、删除,/proc软链接返回的路径会失效或者不准确
- 需要注意
dirfd、realpath的错误返回处理,避免出现空指针或者缓冲区溢出问题
内容的提问来源于stack exchange,提问作者Adam Lee
相关产品推荐
相关产品推荐

