C++: Getting a temporary file, cross-platform

34,878

Solution 1

The Boost Filesystem library, from version 3 of that library, can be used to create a temporary file name. It also offers a crisp solution. Indeed, the following C++ code should be platform independent:

// 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

The filesystem path object temp can be used to open a file or create a subdirectory, while the string object tempstr offers the same information as a string.

Solution 2

The standard C library contains a function called tmpfile, it probably does what you need: http://www.cplusplus.com/reference/clibrary/cstdio/tmpfile/

You can use it in C++ programs as well.

EDIT:
If you need only file name, you can use tmpnam, it doesn't delete the file when fclose is called. It returns full file path, including the temp directory.

The C way:

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

Solution 3

If you use Qt: QTemporaryFile class is perfect.

Solution 4

Since C++17, you can use std::filesystem::temp_directory_path().

Solution 5

You can use the C Standard Library function tmpfile.

Share:
34,878

Related videos on Youtube

orlp
Author by

orlp

Computer Science PhD student at CWI Amsterdam. Cryptography, information theory, compression, computer graphics, low-level optimization, discrete mathematics, algorithms &amp; data structures - it all interests me! Favourite languages: Rust, Python, C++, C. Achievements: Gold C++ badge #238 Gold Python badge #236 Gold C badge #225 #1021 to reach 100,000 reputation Pattern-defeating quicksort

Updated on March 09, 2022

Comments

  • orlp
    orlp over 1 year

    I'm looking for a cross-platform way of getting designated a temporary file. For example in linux that would be in the /tmp dir and in Windows in something akin to C:\Users\Username\AppData\Local\Temp.

    Does a cross-platform (Boost?) solution to this exist?

    EDIT:

    I need this file to exist until the program terminates. tmpfile() does not guarantee that. Quoting from ccpreference:

    The temporary file created is automatically deleted when the stream is closed (fclose) or when the program terminates normally.

    • jwd
      jwd over 12 years
      Could you comment on how using tmpnam fails to suit your purposes?
    • orlp
      orlp over 12 years
      @jwd: It doesn't - sorry, I forgot to accept an answer.
  • orlp
    orlp over 12 years
    This is no solution for me. I need the guarantee of the file's existance until the exit of the program. Quoting from ccpreference: "The temporary file created is automatically deleted when the stream is closed (fclose)."
  • orlp
    orlp over 12 years
    Same comment as on James': This is no solution for me. I need the guarantee of the file's existance until the exit of the program. Quoting from ccpreference: "The temporary file created is automatically deleted when the stream is closed (fclose)."
  • James McNellis
    James McNellis over 12 years
    @nightcracker: Ok... so don't close the file stream until you are done using the temporary file?
  • orlp
    orlp over 12 years
    Won't that block access from external programs (that's the whole point, I need a temporary file for other programs to read)? I was thinking of using tmpnam.
  • davka
    davka over 12 years
    @nightcracker: how would the external programs know the name of the file to read? Are you sending it to them in some way? This feels like contradicting the idea of a temp file
  • André Puel
    André Puel about 12 years
    From GCC on linux: warning: the use of tmpnam' is dangerous, better use mkstemp' -- But I guess that mkstemp is not crossplataform.
  • jwd
    jwd about 12 years
    @André: mkstemp has the same problem as tmpfile with regard to the original question's constraints - it just gives you a file handle back. But you're right, tmpnam is insecure, as noted.
  • Frerich Raabe
    Frerich Raabe almost 12 years
    Using tmpnam means introducing a race condition, too.
  • malat
    malat almost 10 years
    From debian documentation: BUGS Never use this function. Use mkstemp(3) or tmpfile(3) instead.
  • Matt Clarkson
    Matt Clarkson over 9 years
    This should be accepted - tmpnam can be an attack vector.
  • Alex Huszagh
    Alex Huszagh over 7 years
    tmpnam also does not work on C++14 compliant systems, like GCC 5.4 under MSYS2. I don't know what a "\s778." is for a temporary name except entirely incorrect for a Windows system. That would be a directory path, not a file path.
  • JE42
    JE42 about 7 years
    unique_path only returns a filename. Use boost::filesystem::temp_directory_path() / boost::filesystem::unique_path() for a complete temporary pathname.
  • Roi Danton
    Roi Danton over 6 years
    For those who are wondering: unique_path() won't be part of std::filesystem due to possible race condition, see wg21.cmeerw.net/lwg/msg7747.
  • mark.kedzierski
    mark.kedzierski over 6 years
    tmpnam doesn't exist on android
  • smac89
    smac89 almost 6 years
    For those wondering what is meant that tmpname introduces a race condition, see this zachburlingame.com/2011/06/…
  • Timmmm
    Timmmm over 5 years
    @MattClarkson This has exactly the same problems as tmpnam().
  • jwm
    jwm about 4 years
    the OP asked how to create a temporary file in a cross-platform manner, not whether it was a good idea. This is not helpful.
  • user997112
    user997112 about 2 years
    This does not help create a temporary file, it just gives you the name of a temporary folder. If you put a file in there it will remain.
  • Adrian B.
    Adrian B. about 2 years
    Does someone know if it's safe with Windows 10's Storage Sense that can delete temporary files ?