【问题标题】:How do you get the filename of a tempfile to use in Linux?如何获取临时文件的文件名以在 Linux 中使用?
【发布时间】:2010-09-06 23:26:48
【问题描述】:

假设我正在用 C 语言创建一个需要使用临时文件的程序。在 /tmp 中创建临时临时文件可能不是一个好主意。是否有函数或操作系统调用为我提供临时文件名,以便我可以开始写入和读取?

【问题讨论】:

    标签: c linux


    【解决方案1】:

    通常不需要实际创建一个命名文件;而是使用文件描述符路径,

    FILE *tmp=tmpfile();
    char path[PATH_MAX+1]={0};
    sprintf(path, "/dev/fd/%d", fileno(tmp));
    printf("%s\n", path);
    

    【讨论】:

      【解决方案2】:

      你应该使用 mkstemp(),因为这是推荐的函数,但它返回一个文件描述符,所以一旦你有了描述符就得到它的名字:

      int fd;
      fd = mkstemp("hdrXXXXXX);
      /* 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);
      

      【讨论】:

      • 请查看URL,这将有助于提高您的内容质量
      • .. 仅当您将其发送到您自己进程中的另一个线程(或者如果您将其发送到您自己的线程)时,这将起作用,如果您将其发送到另一个进程,它将不起作用一个不同的 /proc/self - 改为使用 /dev/fd/%d ,那么它将与您自己进程中的线程和不同进程一起使用
      【解决方案3】:

      问题是如何生成一个临时文件name。 mkstemp 和 tmpfile 都没有为调用者提供名称,它们分别返回文件描述符或文件句柄。

      【讨论】:

      • 那问题应该改了。
      • 不正确:mkstemp 确实 为调用者提供了一个名称,因为它修改了给定的模板。调用者需要提供一个模板,但这是一个相对简单的事情,选择一个临时目录(例如 $TMPDIR、P_tmpdir 或“/tmp”)和一个前缀,后跟六个 X。
      • 啊,微妙。因此,在不使文件悬空的情况下获得唯一文件名的唯一“好”方法是:1) 使用以 XXXXXX 结尾的字符缓冲区调用 mkstemp。 2) 关闭mkstemp 返回的文件描述符。 3) 取消链接 mkstemp 留在“模板”参数中的文件名。能不能再优雅一点?
      • 是的,我最近花了很长时间想出了一个可移植的 Unix/Windows 临时文件类。在 Linux 上,您基本上必须在知道文件名 (mkstemp) 和自动关闭文件 (tmpfile) 之间做出选择。在 Windows 上,CreateFile 有一个关闭时删除标志,但没有 mkstemp 和一个有很多警告的 tmpfile(根目录?!)。最后,我只是使用加密 PRNG 编写了自己的唯一名称生成器来生成 128 位十六进制后缀。
      • @Mark:一旦你取消链接文件名,就不能保证它是唯一的了。试图获得一个唯一的文件名而不创建它作为 same operation 的一部分的问题从根本上是错误的。需要文件的存在才能充当锁。
      【解决方案4】:

      @garethm:

      我相信您要查找的函数称为 tmpnam。

      你绝对应该使用tmpnam。它存在我在回答中提到的竞争条件问题:在确定名称和打开它之间,另一个程序可能会创建文件或指向它的符号链接,这是一个巨大的安全漏洞。

      tmpnam 手册页明确表示不要使用它,而是使用 mkstemptmpfile

      【讨论】:

        【解决方案5】:

        不确定 C 库中的任何内容,但您可以在 shell 中使用 mktemp 执行此操作。

        【讨论】:

          【解决方案6】:

          绝对:man mkstemp。

          手册页有示例用法。

          【讨论】:

            【解决方案7】:

            您可以为此目的使用mkstemp(3) 函数。另一种选择是tmpfile(3) 函数。 您选择其中的哪一个取决于您是希望将文件作为 C 库文件流(tmpfile 这样做)还是直接文件描述符(mkstemp)打开。 tmpfile 函数还会在您程序完成时自动删除文件。

            使用这些函数的优点是它们避免了确定唯一文件名和创建文件之间的竞争条件 - 例如,两个程序不会尝试同时创建同一个文件。

            有关更多详细信息,请参阅这两个函数的手册页。

            【讨论】:

            • mkstemp 只返回在新文件上打开的文件描述符,但您也可以获得它的最终名称,因为 mkstemp 替换了模板的 XXXXXX 字符。
            猜你喜欢
            • 1970-01-01
            • 2012-08-14
            • 1970-01-01
            • 1970-01-01
            • 2011-07-24
            • 2017-05-03
            • 1970-01-01
            • 1970-01-01
            • 2012-07-05
            相关资源
            最近更新 更多