C 如何获取要在Linux中使用的临时文件的文件名?

C 如何获取要在Linux中使用的临时文件的文件名?,c,linux,C,Linux,假设我正在用C语言创建一个需要使用临时文件的程序。在/tmp中创建临时临时文件可能不是一个好主意。是否有函数或操作系统调用为我提供临时文件名,以便我可以开始从中写入和读取?您可以为此使用该函数。另一种选择是函数。 选择哪一个取决于您是希望将文件作为C库文件流打开(这是tmpfile所做的),还是直接文件描述符(mkstemp)。tmpfile功能还可以在程序完成时自动删除文件 使用这些函数的优点是,它们避免了确定唯一文件名和创建文件之间的竞争条件——例如,两个程序不会试图同时创建同一个文件 有关

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

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

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


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

绝对:man mkstemp


手册页有示例用法。

不确定C库中的任何内容,但您可以在shell中使用。

@garethm:

我相信您正在寻找的函数名为tmpnam

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


tmpnam
手册页特别指出不要使用它,而是使用
mkstemp
tmpfile

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

您应该使用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);

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

FILE*tmp=tmpfile();
字符路径[path_MAX+1]={0};
sprintf(路径“/dev/fd/%d”,文件号(tmp));
printf(“%s\n”,路径);

那么问题应该更改。不正确:mkstemp确实为调用者提供了一个名称,因为它修改了给定的模板。调用者需要提供一个模板,但选择一个临时目录(例如$TMPDIR、P_TMPDIR或“/tmp”)和一个前缀,后跟六个X.Ahh,这是一个相对简单的问题。因此,在不让文件悬空的情况下获得唯一文件名的唯一“好”方法是:1)使用以XXXXXX结尾的字符缓冲区调用mkstemp。2) 关闭文件描述符mkstemp returns。3) 取消链接mkstemp留在“template”参数中的文件名。是的,我最近花了很长时间设计了一个可移植的Unix/Windows临时文件类。在Linux上,您基本上必须在知道文件名(mkstemp)和自动关闭文件(tmpfile)之间进行选择。在Windows上,CreateFile有一个delete-On-close标志,但没有mkstemp和一个带有大量警告的tmpfile(根目录?!)。最后,我用crypto PRNG编写了我自己的唯一名称生成器,生成了一个128位十六进制后缀。@马克:一旦你取消了文件名的链接,就不能保证它是唯一的了。尝试获取唯一文件名而不将其创建为同一操作的一部分的问题从根本上说是错误的。文件的存在需要用作锁。请选中此复选框,这将有助于提高您的内容质量。。仅当您将其发送到自己进程中的另一个线程(或者如果您将其发送到自己的线程)时,此功能才起作用;如果您将其发送到另一个具有不同
/proc/self
的进程,则此功能将不起作用-改为使用
/dev/fd/%d
,然后它将与您自己进程中的线程一起工作,不同的processesmkstemp只返回一个新文件上打开的文件描述符,但您也可以得到它的最终名称,因为mkstemp替换模板的XXXXXX字符。