2011-04-07 77 views
33

我正在寻找获取指定临时文件的跨平台方式。例如,在Linux中将在/tmp目录中,并在Windows中的一些蹩脚的命名Internet Explorer临时目录中。C++:获取临时文件,跨平台

是否存在一个跨平台(Boost?)解决方案?

编辑

我需要这个文件存在,直到程序终止。 tmpfile()不保证。从ccpreference引述:

创建的临时文件被自动删除当流被关闭(FCLOSE)或当在程序正常终止。

+1

所以,不要关闭它。 – 2011-04-07 20:02:10

+1

您可否评论如何使用'tmpnam'不符合您的目的? – jwd 2011-05-04 21:21:24

+0

@jwd:没有 - 对不起,我忘了接受答案。 – orlp 2011-05-05 12:15:58

回答

65

Boost Filesystem可以使用该库的版本3创建临时文件名。它还提供了一个清晰的解决方案。事实上,下面的C++代码应该是独立于平台:

// Boost.Filesystem VERSION 3 required 
#include <string> 
#include <boost/filesystem.hpp> 
boost::filesystem::path temp = boost::filesystem::unique_path(); 
const std::string tempstr = temp.native(); // optional 

文件系统路径对象temp可以用来打开文件或创建一个子目录,而字符串对象tempstr提供了相同的信息串。有关更多详细信息,请参阅http://www.boost.org

+2

这应该被接受 - 'tmpnam'可以是一个攻击媒介。 – 2014-08-07 14:44:31

+13

unique_path只返回一个文件名。使用boost :: filesystem :: temp_directory_path()/ boost :: filesystem :: unique_path()来获取完整的临时路径名。 – JE42 2016-11-07 04:57:46

+1

对于那些想知道的人:由于可能的竞争条件,'unique_path()'不会成为'std :: filesystem'的一部分,请参阅https://wg21.cmeerw.net/lwg/msg7747。 – 2017-04-25 14:36:56

4

您可以使用C标准库函数tmpfile

+0

这对我来说无法解决。我需要保证文件存在,直到程序退出。从ccpreference引用:“当流关闭(fclose)时,创建的临时文件将自动删除。” – orlp 2011-04-07 19:21:33

+1

@nightcracker:好的...所以不要关闭文件流,直到完成使用临时文件? – 2011-04-07 19:27:30

+0

这不会阻止从外部程序的访问(这是整个问题,我需要一个临时文件供其他程序读取)?我正在考虑使用[tmpnam](http://www.cplusplus.com/reference/clibrary/cstdio/tmpnam/)。 – orlp 2011-04-07 19:28:45

5

标准C库包含一个名为tmpfile功能,它可能做你所需要的:http://www.cplusplus.com/reference/clibrary/cstdio/tmpfile/

可以在C++程序中使用它。

编辑:
如果您只需要文件名,你可以使用tmpnam,它不会删除该文件时FCLOSE被调用。它返回完整的文件路径,包括临时目录。

的C方式:

const char *name = tmpnam(NULL); // Get temp name 
FILE *fp = fopen(name, "w"); // Create the file 
// ... 
fclose(fp); 
remove(name); 
+0

与詹姆斯的评论相同:对我来说这不是解决方案。我需要保证文件存在,直到程序退出。从ccpreference引用:“当流关闭(fclose)时,创建的临时文件将自动删除。” – orlp 2011-04-07 19:23:11

+5

使用'tmpnam'也意味着引入竞争条件。 – 2012-01-13 09:33:35

+0

tmpnam也不适用于C++ 14兼容系统,如MSYS2下的GCC 5.4。我不知道什么是“\ s778”。是一个临时名称,除非Windows系统完全不正确。这将是一个目录路径,而不是文件路径。 – 2016-07-05 19:45:25

2

编辑:由于您似乎喜欢Boost的想法,Robbie Morrison's answer可能对您更好。

我原来的答案仍然在下面,但是任何人都会阅读:请注意,tmpnam是不安全的。此外,某些平台(如Windows)可能已经损坏,bug,脑残或甚至缺少实现。


tmpnam如果你不喜欢tmpfile?

从链接:

的文件中创建这种方式,不像那些 用tmpfile建立的不是 关闭时自动删除;你应该调用remove来删除这个文件 一旦关闭。

特别是如果您需要另一个程序来知道文件的名称,这似乎更合适,因为tmpfile根本不会给你一个名字。

我认为这不是安全的,但如果这是一个问题。 这是link describing some of those issues

+2

从linux上的GCC:警告:'tmpnam'的使用是危险的,更好的使用'mkstemp' - 但我想mkstemp不是交错布局。 – 2011-09-28 13:34:56

+0

@André:对于原始问题的约束,'mkstemp'与'tmpfile'有相同的问题 - 它只是给你一个文件句柄。但是你说得对,'tmpnam'是不安全的,正如所指出的那样。 – jwd 2011-09-28 17:30:25

+0

来自debian文档:BUGS不要使用这个函数。改为使用mkstemp(3)或tmpfile(3)。 – malat 2013-11-26 14:52:16

0

程序之间的沟通比随机临时文件有更好的方法。你可以使用管道进行通讯吗?使用本地主机套接字怎么样?

如果您坚持使用文件,只需让程序使用一个名称,可能基于启动时间。