【发布时间】:2012-11-22 13:06:07
【问题描述】:
我正在遍历一个目录,当一个项目符合某些条件时,我将其删除。我可以在循环中安全地执行此操作,还是必须将路径保存在数组中并稍后删除?
我在boost::filesystem docs没有找到相关信息。
【问题讨论】:
我正在遍历一个目录,当一个项目符合某些条件时,我将其删除。我可以在循环中安全地执行此操作,还是必须将路径保存在数组中并稍后删除?
我在boost::filesystem docs没有找到相关信息。
【问题讨论】:
引用docs of boost::filesystem::directory_iterator 附注的第一部分(重点是我自己的):
执行目录迭代的程序可能希望测试通过取消引用目录迭代器获得的路径是否确实存在。它可能是指向不存在文件的符号链接。 为了删除和重命名条目而递归遍历目录树的程序可能希望避免跟随符号链接。
我很清楚,为了删除文件而迭代目录是官方支持的用例,因此不会使迭代器无效。另外,引用该说明的第二部分:
如果在为目录构建 directory_iterator 之后将文件从目录中删除或添加到目录中,则未指定迭代器的后续递增是否会导致迭代器的值是已删除或添加的目录条目.请参阅 ISO/IEC 9945 readdir_r()。
这是关于在遍历目录时是否会出现已删除文件的非常具体的声明。同样,我知道迭代过程本身在任何情况下都是有效的。
请注意,ISO/IEC 9945 的措辞相似。
【讨论】:
boost::filesystem::recursive_directory_iterator 迭代时删除了文件(注意recursive),它确实失败了迭代。
在 Windows 上确实如此,但我发现了一个 Ubuntu,在该 Ubuntu 上,迭代器在删除后会失效,因此下一次访问会引发异常。
所以我最终使用了这样的东西:
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++;
}
}
}
【讨论】: