是否可以在C中获取文件描述符(Linux)的文件名?
答案 0 :(得分:104)
您可以在/proc/self/fd/NNN
上使用readlink
,其中NNN是文件描述符。这将为您提供文件的名称,就像它打开时一样 - 但是,如果从那时起移动或删除文件,它可能不再准确(尽管Linux可以在某些情况下跟踪重命名)。要验证stat
给出的文件名和fstat
您拥有的fd,并确保st_dev
和st_ino
相同。
当然,并非所有文件描述符都引用文件,对于那些文档描述符,您会看到一些奇怪的文本字符串,例如pipe:[1538488]
。由于所有真实文件名都是绝对路径,因此您可以轻松确定哪些文件名。此外,正如其他人所指出的那样,文件可以有多个指向它们的硬链接 - 这只会报告它打开的链接。如果要查找给定文件的所有名称,则只需遍历整个文件系统。
答案 1 :(得分:72)
我在Mac OS X上遇到此问题。我们没有/proc
虚拟文件系统,因此接受的解决方案无效。
我们确实为F_GETPATH
提供了fcntl
命令:
F_GETPATH Get the path of the file descriptor Fildes. The argu-
ment must be a buffer of size MAXPATHLEN or greater.
因此,要获取与文件描述符关联的文件,您可以使用以下代码段:
#include <sys/syslimits.h>
#include <fcntl.h>
char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
// do something with the file path
}
由于我从未记得MAXPATHLEN
的定义,我认为来自syslimits的PATH_MAX
会没问题。
答案 2 :(得分:21)
在Windows中,通过GetFileInformationByHandleEx传递FileNameInfo,您可以检索文件名。
答案 3 :(得分:15)
正如Tyler指出的那样,由于给定的FD可能对应于0个文件名(在各种情况下)或者&gt;,因此无法“直接且可靠地”执行所需的操作。 1(多个“硬链接”是一般描述后一种情况的方式)。如果你仍然需要具有所有限制的功能(关于速度和获得0,2,......结果而不是1的可能性),这里是你如何做到的:首先,fstat FD - - 这会在生成的struct stat
中告诉您,该文件所处的设备,它有多少硬链接,是否是特殊文件等。这可能已经回答了您的问题 - 例如如果有0个硬链接,你就会知道磁盘上实际上没有相应的文件名。
如果统计数据给你带来希望,那么你必须在相关设备上“走树”目录,直到找到所有硬链接(或者只是第一个,如果你不需要多个硬链接,那么一个会做)。为此,您使用readdir(当然还有opendir&amp; c)以递归方式打开子目录,直到您在struct dirent
中找到与原始struct stat
中相同的inode编号(如果你想要整个路径,而不仅仅是名称,那么你需要向后走一段目录来重建它。)
如果这种一般方法是可以接受的,但是你需要更详细的C代码,让我们知道,它写起来并不难(虽然如果它没用,我宁愿不写它,也就是说你无法承受不可避免的速度性能或获得的可能性!= 1为您的申请目的的结果; - )。
答案 4 :(得分:8)
在将此视为不可能之前,我建议您查看lsof命令的源代码。
可能存在限制,但lsof似乎能够确定文件描述符和文件名。这些信息存在于/ proc文件系统中,因此应该可以从您的程序中获取。
答案 5 :(得分:5)
您可以使用fstat()通过struct stat获取文件的inode。然后,使用readdir(),您可以将找到的inode与目录中存在的inode(struct dirent)进行比较(假设您知道目录,否则您将不得不搜索整个文件系统)并找到相应的文件名。 讨厌?
答案 6 :(得分:3)
不可能。文件描述符在文件系统中可能有多个名称,或者根本没有名称。
编辑:假设您正在谈论一个普通的旧POSIX系统,没有任何特定于操作系统的API,因为您没有指定操作系统。