C 从 FILE* 打印文件路径

joi*_*doi 6 c linux printf fopen file

FILE * fd = fopen ("/tmp/12345","wb");
Run Code Online (Sandbox Code Playgroud)

如果我有变量fd,我如何打印文件路径?(/tmp/12345) 在 Linux 环境中。

PSk*_*cik 6

你不能。不仅仅是标准 C。

在 Linux 上,您可以执行以下操作:

#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <stdlib.h>


int print_filename(FILE *f)
{
    char buf[PATH_MAX];
    char fnmbuf[sizeof "/prof/self/fd/0123456789"];
    sprintf(fnmbuf,"/proc/self/fd/%d", fileno(f));
    ssize_t nr;
    if(0>(nr=readlink(fnmbuf, buf, sizeof(buf)))) return -1;
    else buf[nr]='\0';
    return puts(buf);
}

int main(void)
{
    FILE * f = fopen ("/tmp/12345","wb");
    if (0==f) return EXIT_FAILURE;
    print_filename(f);

}
Run Code Online (Sandbox Code Playgroud)

  • 请注意: [`readlink()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html) 不会以 null 终止字符串。您需要捕获它返回的值(包含名称的字节数组的长度),并在将现在的字符串传递给“puts()”之前将空终止符放在适当的位置。 (3认同)

Joh*_*ode 5

没有从FILE *对象中检索路径名的标准方法,主要是因为您可以拥有与命名文件(stdinstdoutstderr、 管道等)无关的流。个别平台可能会提供实用程序来从流中检索路径,但您必须检查该平台的文档。

否则,您需要手动跟踪该信息。


D. *_*ael 5

由于 MacOS 没有/proc,fcntl是获取文件描述符路径的不错选择!

这是一个工作示例:

#include <sys/syslimits.h>
#include <fcntl.h>

char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
    printf("%s", filePath);
}
Run Code Online (Sandbox Code Playgroud)

但它仅适用于 MacOS,对于 Linux PSkocik 的解决方案使用readlink似乎是最好的答案。

  • 有趣的!不过,尚未由 POSIX 标准化([`fcntl()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html))。 (2认同)