Win32已实现句柄获取文件名,POSIX下如何通过文件描述符获取?
POSIX环境下通过文件描述符获取文件名的实现
POSIX环境下可以实现类似Win32通过句柄获取文件名的功能,但不同类Unix系统的实现方式略有差异:
Linux系统实现
Linux系统可借助/proc文件系统提供的符号链接获取路径——/proc/self/fd/[fd]指向对应文件描述符打开的实际文件路径,通过readlink函数读取该链接内容即可:
#include <unistd.h> #include <string.h> #include <stdio.h> #include <string> std::string GetFileName(int fd) { char link_path[64]; snprintf(link_path, sizeof(link_path), "/proc/self/fd/%d", fd); char buf[PATH_MAX]; ssize_t len = readlink(link_path, buf, sizeof(buf) - 1); if (len == -1) { return "<无法获取路径>"; } buf[len] = '\0'; // readlink不会自动添加字符串结束符 return buf; }
注意:
- 若文件是临时文件、匿名文件(如管道、socket),或进程无
/proc访问权限,该方法会失败 - 路径长度可能超过
PATH_MAX,实际场景可考虑动态分配内存处理超长路径
BSD/macOS系统实现
这类系统没有/proc文件系统,可使用fcntl函数结合F_GETPATH扩展命令获取路径:
#include <fcntl.h> #include <unistd.h> #include <string> std::string GetFileName(int fd) { char buf[PATH_MAX]; int ret = fcntl(fd, F_GETPATH, buf); if (ret == -1) { return "<无法获取路径>"; } return buf; }
通用注意事项
- 无法保证总能获取到有效文件名:比如文件被删除后,文件描述符仍有效,但路径已不存在;若文件通过硬链接打开,仅能获取其中一个关联路径
F_GETPATH属于BSD系扩展,并非POSIX标准接口,跨平台使用时需做兼容性判断
内容的提问来源于stack exchange,提问作者Alexey Starinsky
相关产品推荐
相关产品推荐

