【问题标题】:Is there a way to get the filename from a `FILE*`? [duplicate]有没有办法从 `FILE*` 中获取文件名? [复制]
【发布时间】:2011-02-01 12:06:27
【问题描述】:

可能重复:
Getting Filename from file descriptor in C

是否有一种简单且(合理)可移植的方式从FILE* 获取文件名?

我使用f = fopen(filename, ...) 打开一个文件,然后将f 传递给其他各种函数,其中一些函数可能会报告错误。我想在错误消息中报告文件名,但避免传递额外的参数。

我可以创建一个自定义包装器struct { FILE *f, const char *name },但可能有更简单的方法吗? (如果FILE* 不是使用fopen 打开的,我不关心结果。)

【问题讨论】:

  • 没有我知道的标准方式; freopen 将允许您更改读/写和二进制/正常模式,但如果您想要名称本身(例如打印错误消息),那么您就不走运了。
  • 我不认为你可以 - 有多个名称指向同一个 inode 的文件呢? (在这种情况下没有“规范”文件名,两者都同样有效)那些不是真正文件的东西(套接字等)呢?
  • stackoverflow.com/questions/1188757/… 中为Linux 回答(您只需使用filenoFILE* 获取fd)。不过,这不是很便携...
  • 如果它必须是 posix-portable,显然 [没有好的解决方案][1]。您还必须考虑到,在许多文件系统上,相同的文件系统对象(在任何文件系统中相当于“inode”)可能有多个名称(例如硬链接)。因此,与其让这件事变得复杂,我只想保存名称。 [1]:bytes.com/topic/c/answers/…

标签: c


【解决方案1】:

在某些平台(如Linux)上,您可能可以通过阅读/proc/self/fd/<number>的链接来获取它,如下所示:

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(void)
{
    char path[1024];
    char result[1024];

    /* Open a file, get the file descriptor. */
    FILE *f = fopen("/etc/passwd", "r");
    int fd = fileno(f); 

    /* Read out the link to our file descriptor. */
    sprintf(path, "/proc/self/fd/%d", fd);
    memset(result, 0, sizeof(result));
    readlink(path, result, sizeof(result)-1);

    /* Print the result. */
    printf("%s\n", result);
}

这将在我的系统上根据需要打印出/etc/passwd

【讨论】:

  • 在匿名管道上打印什么?
  • @dmckee: pipe:[&lt;some number&gt;]
【解决方案2】:

这有点困难,因为 FILE* 可以从根本不与命名文件关联的文件句柄读取/写入(例如未命名的管道或套接字)。 您可以使用 fileno() 获取文件句柄,然后有系统特定的方法来了解文件名。以下是关于如何在 Linux 下执行此操作的讨论:

Getting Filename from file descriptor in C

在 Windows 下,这也不容易:

http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx(作为额外的步骤,您使用 _get_osfhandle() 从 c 库文件描述符中获取 Windows 文件句柄)

【讨论】:

    猜你喜欢
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-29
    • 2017-03-25
    • 1970-01-01
    • 2022-10-14
    • 2020-02-29
    相关资源
    最近更新 更多