How to create a std::ofstream to a temp file?

后端 未结 4 1363
醉梦人生
醉梦人生 2020-12-24 12:45

Okay, mkstemp is the preferred way to create a temp file in POSIX.

But it opens the file and returns an int, which is a file descriptor. F

相关标签:
4条回答
  • 2020-12-24 13:10

    Maybe this will work:

    char tmpname[256];
    ofstream f;
    sprintf (tmpname, "/tmp/tmpfileXXXXXX");
    int fd = mkstemp(tmpname);
    ofstream f(tmpname);
    

    I haven't tried it, but you can check.

    0 讨论(0)
  • 2020-12-24 13:14
    char tempFileName[20]; // name only valid till next invocation of tempFileOpen
    ofstream tempFile;
    void tempFileOpen()
    {
        strcpy(tempFileName, "/tmp/XXXXXX");
        mkstemp(tempFileName);
        tempFile.open(tempFileName);
    }
    

    This code works for me with GCC/libstdc++6 4.8.4 and Clang 3.9 as well. Thanks to the other replies as well which were helpful to me.

    0 讨论(0)
  • 2020-12-24 13:16

    I think this should work:

        char *tmpname = strdup("/tmp/tmpfileXXXXXX");
        ofstream f;
        int fd = mkstemp(tmpname);
        f.attach(fd);
    

    EDIT: Well, this might not be portable. If you can't use attach and can't create a ofstream directly from a file descriptor, then you have to do this:

    char *tmpname = strdup("/tmp/tmpfileXXXXXX");
    mkstemp(tmpname);
    ofstream f(tmpname);
    

    As mkstemp already creates the file for you, race condition should not be a problem here.

    0 讨论(0)
  • 2020-12-24 13:34

    I've done this function:

    #include <stdlib.h>
    #include <fstream>
    #include <iostream>
    #include <vector>
    
    std::string open_temp(std::string path, std::ofstream& f) {
        path += "/XXXXXX";
        std::vector<char> dst_path(path.begin(), path.end());
        dst_path.push_back('\0');
    
        int fd = mkstemp(&dst_path[0]);
        if(fd != -1) {
            path.assign(dst_path.begin(), dst_path.end() - 1);
            f.open(path.c_str(), 
                   std::ios_base::trunc | std::ios_base::out);
            close(fd);
        }
        return path;
    }
    
    int main() {
        std::ofstream logfile;
        open_temp("/tmp", logfile);
        if(logfile.is_open()) {
            logfile << "hello, dude" << std::endl;
        }
    }
    

    You should probably make sure to call umask with a proper file creation mask (I would prefer 0600)- the manpage for mkstemp says that the file mode creation mask is not standardized. It uses the fact that mkstemp modifies its argument to the filename that it uses. So, we open it and close the file it opened (so, to not have it opened twice), being left with a ofstream that is connected to that file.

    0 讨论(0)
提交回复
热议问题