我想要的是:
void printFname(FILE * f)
{
char buf[255];
MagicFunction(f,buf);
printf("File name: %s",buf);
}
所以,我需要的只是“MagicFunction”,但不幸的是我还没有找到这样的......
有没有办法使用操作系统库来实现?(windows.h、cocoa.h、posix.h 等)
我想要的是:
void printFname(FILE * f)
{
char buf[255];
MagicFunction(f,buf);
printf("File name: %s",buf);
}
所以,我需要的只是“MagicFunction”,但不幸的是我还没有找到这样的......
有没有办法使用操作系统库来实现?(windows.h、cocoa.h、posix.h 等)
没有这样的功能。可能没有文件名,或者与FILE *
. 在 Unix 上,程序可以在文件被重命名或删除后继续引用文件,这可能意味着您有一个FILE *
没有名称的文件。或者可以对文件进行更多的硬链接,这意味着一个文件可以有多个名称;你会选哪一个?为了进一步混淆,可以通过在包含该文件的目录上安装文件系统来临时隐藏文件。该文件仍将在磁盘上,以其原始路径名,但该文件将无法在该路径上访问,因为挂载遮住了它。
也有可能FILE *
根本不对应文件系统上的文件。虽然他们通常会这样做,但您可以使用任何文件描述符创建一个fdopen()
,并且该文件描述符可能是管道、套接字或其他在磁盘上从未有过路径的类似文件的对象。在某些版本的 C 库中,您可以打开一个字符串流(例如,fmemopen()
在 glibc 中),因此FILE *
实际上只对应一个内存缓冲区。
如果您关心名称,最好只跟踪打开文件时的名称。
有一些 hacky 方法来近似获取文件名;如果您只是将其用于调试或信息目的,那么它们可能就足够了。其中大多数将需要对文件描述符而不是 进行操作FILE *
,因为文件描述符是引用文件的较低级别的方式。要获取文件描述符,请在fileno()
上运行FILE *
,并记住检查错误以防万一没有与之关联的文件描述符FILE *
。
在 Linux 上,您可以对文件描述符readlink()
在"/proc/self/fd/fileno"
哪里进行操作。fileno
这将显示文件打开时文件的文件名,或指示它是哪种其他文件描述符的字符串,如套接字或 inotify 句柄。FreeBSD 和 NetBSD 具有 Linux 仿真层,其中包括仿真 Linux 风格的 procfs;如果您安装与 Linux 兼容的 procfs,您也许可以在这些设备上执行此操作,尽管我没有它们可用于测试。
在 Mac OS X 上,您没有/proc/self/fd
. 如果您不关心找到原始文件名,但引用该文件的其他文件名可以工作(这样您可以将其传递给另一个程序),您可以构造一个:/.vol/deviceid/inode
. 例如,/.vol/234881030/281363
。要获取这些值,fstat()
请在文件描述符上运行,st_dev
然后st_ino
在生成的struct stat
.
在 Windows 上,文件和文件系统的工作方式与 Unix 完全不同。显然,可以将文件映射回 Windows 上的名称。从 Windows Vista 开始,您可以简单地调用GetFinalPathNameByHandle()
. 这需要一个HANDLE
; HANDLE
要从文件描述符中获取,请调用_get_osfhandle()
. 在 Windows Vista 之前,您需要做更多的工作,如本文所述。请注意,在 Windowsfileno()
上名为_fileno()
,尽管前者可能会出现警告。
更进一步进入 hacky 领域,您可以使用更多技术。您可以使用lsof
,或者您可以提取它用于解析路径名的代码。lsof
实际上直接查看内核内存,从内核的名称缓存中提取信息。这有几个限制,如常见问题解答中所述lsof
。当然,您需要 root 或同等权限才能直接或使用 suid/sgid 二进制文件执行此操作。
最后,对于查找一个或多个与打开文件匹配的文件名的可移植但缓慢的解决方案,您可以使用fstat()
文件描述符找到设备和 inode 编号,然后递归遍历stat()
每个文件的文件系统,直到找到一个文件匹配设备和 inode 号。记住我上面提到的警告;您可能找不到匹配的文件,匹配的文件不止一个,即使您没有找到任何匹配的文件,该文件可能仍然存在,但被挂载点隐藏。当然,可能会有竞争条件;某些东西可能会以您在遍历层次结构时永远看不到的方式重命名文件。
没有这样的标准功能。
你fopen()
自己吗?如果是这样,FILE *
请自己维护文件名哈希表。
否则,一般情况下是不可能的。
我认为即使在 windows.h、coca.h 或 unistd.h 中也没有这样的功能。很可能是你自己写的。只做一个
struct myFile {
FILE *fh;
char *filename;
}
并将这样的结构保存到数组中,struct myFile
并在数组上MagicFunction(f,b)
行走,寻找等于 的地址f
。