C++ Catch if the file was removed

Viewed 724

I have some basic code that runs in a loop and writes to file. It looks along the lines of:

std::ofstream myFile;
myFile.open("file.txt", std::ofstream::out);
while (true)
{
    if (myFile.is_open() && myFile.good())
    {
        myFile << "test" <<std::endl;
    }
    if (myFile.fail())
    {
        std::cout << "Error\n";
    }
}

Everything works fine and errors if I manually insert a myFile.setstate() and set it to fail.

However, if I have the program writing to a file in a loop and then I manually go ahead and delete the file... The program appears to continue writing to file as if it still exists. No error is thrown. I thought maybe using flush() would work since I expected it to set the failbit, but the behaviour didn't seem to change. What am I doing wrong?

Is there a way to check if the file suddenly went missing, without resorting to trying to call open() again? (I'm trying to avoid .open() and .close() in a loop. Rather open at start, and then have it closed when it goes out of scope.)

2 Answers

C++17 has std::filesystem that includes an exists method. Or you can use boost::filesystem with an older compiler.

#ifdef __cpp_lib_filesystem
  #include <filesystem>
  namespace FS = std::filesystem;
#else
  #include <boost/filesystem.hpp>
  namespace FS = boost::filesystem;
#endif

At the start of your loop:

  if(myFile.is_open() && !FS::exists("file.txt"))
  {
    myFile.close();
    myFile.open("file.txt", std::ofstream::out | std::ofstream::app);
  }

boost::filesystem::exists uses ::stat() which according to https://stackoverflow.com/a/12774387/69231 takes just over a 1 microsecond, so is not likely to cause much impact on speed.

Related