Search code examples
c++stdfstream

How to truncate a file while it is open with fstream


I know it is possible to truncate a file with

std::fstream fs(mypath, std::fstream::out | std::fstream::trunc);

but I need to read the file, truncate it, then write new contents all with the same file handle (so the whole operation is atomic). Anyone?


Solution

  • I don't think you can get "atomic" operation but using the Filesystem Technical Specification that has now been accepted as part of the Standard Library (C++17) you can resize the file like this:

    #include <fstream>
    #include <sstream>
    #include <iostream>
    #include <experimental/filesystem> // compilers that support the TS
    // #include <filesystem> // C++17 compilers
    
    // for readability
    namespace fs = std::experimental::filesystem;
    
    int main(int, char*[])
    {
        fs::path filename = "test.txt";
    
        std::fstream file(filename);
    
        if(!file)
        {
            std::cerr << "Error opening file: " << filename << '\n';
            return EXIT_FAILURE;
        }
    
        // display current contents
        std::stringstream ss;
        ss << file.rdbuf();
        std::cout << ss.str() << '\n';
    
        // truncate file
        fs::resize_file(filename, 0);
        file.seekp(0);
    
        // write new stuff
        file << "new data";
    }