问题
I am iterating through a directory, and when an item matches some criteria, I delete it. Can I do it safely from within the loop, or to I have to save paths in an array and delete then later?
I did not find a relevant information in boost::filesystem docs.
回答1:
Quoting the first part of a note attached to the docs of boost::filesystem::directory_iterator (emphasis is my own):
Programs performing directory iteration may wish to test if the path obtained by dereferencing a directory iterator actually exists. It could be a symbolic link to a non-existent file. Programs recursively walking directory trees for purposes of removing and renaming entries may wish to avoid following symbolic links.
I becomes clear that iterating a directory for the purpose of removing files is an officially supported use case and therefore will not invalidate the iterator. Also, quoting the second part of that note:
If a file is removed from or added to a directory after the construction of a directory_iterator for the directory, it is unspecified whether or not subsequent incrementing of the iterator will ever result in an iterator whose value is the removed or added directory entry. See ISO/IEC 9945 readdir_r().
This is a very specific statement about whether or not a removed file will appear while iterating over a directory. Again, I understand that the iteration process itself remains valid in any case.
Note that ISO/IEC 9945 has similar wording.
回答2:
On Windows it's true but I've found an Ubuntu on which the iterator gets invalidated after the remove so the next access throws an exception.
So I ended up using something like this:
recursive_directory_iterator end;
for (recursive_directory_iterator itr(folderPath); itr != end; )
{
path filePath = *itr++;
if (is_regular_file(filePath) && filePath.string().find(filter) != std::string::npos)
{
if (remove(filePath))
{
removedFilesCounter++;
}
}
}
来源:https://stackoverflow.com/questions/13513369/is-boostfilesystemdirectory-iterator-invalidated-by-deletion