I wrote a function which should delete a directory and all files and folders in it, but it got some troubles. For my targets, I made special directory for experiments. This directory stores some files and one folder. And this folder (sub-directory) also contains 1 or 2 files. My function successfully removes sub-directory and all files in it. And all files in main directory are also removes successfully. But when the function starts to remove main directory - it fails. It seems like rmdir returns not 0 and I don't know why, because subdirectory removes well.
As an argument it takes string like "D:\new".
Where new is main directory that should be removed with everything in it. Here is code of this function:
void OperationsWithDirectories::RemovingCycle(string _path)
{
string wayToFile; // string to hold the path to the directory without mask
string deletedFile; // string which would hold the way to deleting file
wayToFile = _path;
_path += "*.*"; // add a mask to the _path string
_finddata_t* fileinfo = new _finddata_t;
long done = _findfirst(_path.c_str(), fileinfo);
int IsContinue = done;
while (IsContinue != -1)
{
deletedFile = wayToFile + fileinfo->name;
if (fileinfo->attrib == _A_SUBDIR)
{
if (strcmp(fileinfo->name, ".") != 0 && strcmp(fileinfo->name, "..") != 0)
{
cout << "\nEnter subdirectory\n";
RemovingCycle(wayToFile + fileinfo->name + "\\"); //recursive func which would start, if subdirectory is exist
cout << "\nOutta subdirectory\n";
}
}
else
{
if ((remove(deletedFile.c_str())) != 0)
cout << "\n\n ERROR IN FILE DELETING\n\n";
else
cout << endl << deletedFile << " - was deleted";
}
IsContinue = _findnext(done, fileinfo);
}
if ((_rmdir(wayToFile.c_str())) != 0)
cout << "\n\nERROR IN DIRECT - " << wayToFile << " DELETING\n\n";
else
cout << "\ndir - " << wayToFile << " was deleted succesfully\n";
}
Is this under Windows? In Windows in particular the problem is that if you remove a file or subfolder, it is not removed immediately but asynchronously "sometime in the future". This can take even quite a long time, especially if someone still has some of the file handles open. And even if not, if your program is "too fast" (or the filesystem under heavy load), when you try to remove the parent folder, the contents might not have been actually removed yet, and the call fails.
Commonly this is solved by moving each sub-file and sub-folder to some temporary location (on the same partition!), and then deleting it. That way the parent folder will be empty and deletable, even though the contents has not been "physically" deleted yet (because everything is already moved outside - the move is synchronous).
You can see this talk for more info on that: https://youtu.be/uhRWMGBjlO8?t=7m30s
In general, handling the filesystem properly really isn't all that simple and there is a lot of space for race conditions.
You can confirm this problem if you put a sleep before deleting each folder, lets say 200ms, to see if giving the system some time to delete the contents "solves" the issue (however that is not a "real solution", it is just to see that it is indeed a timing issue).
Note that it is not a problem if you move-and-delete and your program terminates before the actual deletion happens - once the delete returned successfully, the Windows OS will take care that the file will be deleted.