c++怎么遍历并删除空文件夹_recursive_directory_iterator应用【详解】

风晨君_7162

风晨君_7162

2026-03-24

736人浏览

原创

不能边遍历边删除空目录,因recursive_directory_iterator内部维护路径栈,删除当前目录会导致后续迭代抛filesystem_error;应先收集所有目录路径、按深度从深到浅排序、再安全判断并删除。

c++怎么遍历并删除空文件夹_recursive_directory_iterator应用【详解】

用 std::filesystem::recursive_directory_iterator 遍历目录时,不能边走边删空文件夹

因为迭代器内部维护着栈式路径状态,一旦你删掉当前正在访问的目录(哪怕它是空的),下一次 ++it 可能抛出 filesystem_error,典型错误是 "No such file or directory" 或 "Permission denied"。这不是 bug,是标准行为——迭代器不保证在底层结构变动后仍有效。

实操建议:

  • 先用 recursive_directory_iterator 收集所有目录路径到 std::vector<:filesystem::path>,按深度**从深到浅**排序(即子目录优先)
  • 再遍历这个列表,对每个路径调用 is_empty() 判断是否为空,再调用 remove()
  • 注意:必须逆序,否则父目录先删了,子目录路径就失效了

is_empty() 判断空目录要小心权限和符号链接

std::filesystem::is_empty(path) 对目录返回 true 仅当它不包含任何目录项(包括隐藏文件、. 和 ..)。但它会失败的情况比你想的多:

  • 路径不存在或不可读 → 抛 filesystem_error,需 try/catch
  • 路径是符号链接且指向不存在的目标 → 默认不解引用,is_empty() 会失败;加 std::filesystem::symlink_option::nofollow 可避免
  • Windows 下遇到 System Volume Information 这类受保护目录,即使有读权限也可能被拒绝访问

稳妥写法是封装一层:

bool safe_is_empty(const std::filesystem::path& p) {
    try {
        return std::filesystem::is_empty(p);
    } catch (const std::filesystem::filesystem_error&) {
        return false; // 无法判断,视为非空,跳过删除
    }
}

递归删空目录的最小可靠实现(C++17)

核心逻辑就三步:收集 → 排序 → 安全删除。不依赖第三方库,也不用自己写 DFS。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 收集阶段用 recursive_directory_iterator + pop 避免重复进入已知子树(可选优化)
  • 排序用 std::sort(v.begin(), v.end(), [](const auto& a, const auto& b) { return a.string().size() > b.string().size(); }) —— 按路径长度降序,基本等价于深度优先逆序
  • 删除前务必检查 is_directory(),防止误删文件;remove() 成功返回 true,失败静默跳过更安全

关键片段示例:

std::vector<:filesystem::path> dirs;
for (auto it = std::filesystem::recursive_directory_iterator(root); it != std::filesystem::recursive_directory_iterator(); ++it) {
    if (it->is_directory()) dirs.push_back(it->path());
}
std::sort(dirs.begin(), dirs.end(), [](const auto& a, const auto& b) {
    return a.string().size() > b.string().size();
});
for (const auto& p : dirs) {
    if (std::filesystem::is_directory(p) && safe_is_empty(p)) {
        std::filesystem::remove(p);
    }
}</:filesystem::path>

Windows 下长路径和只读属性是隐形拦路虎

即便逻辑完全正确,remove() 在 Windows 上仍可能失败,常见原因:

  • 路径超过 MAX_PATH(260 字符)→ 必须启用长路径支持(注册表或清单文件),且路径前加 \\?\ 前缀(std::filesystem 内部已处理,但你的输入路径不能含相对符号如 ../)
  • 目录含只读属性(尤其 Git 创建的空目录)→ remove() 不自动清除属性,得先用 permissions(p, perms::owner_write, perm_options::add)
  • 防病毒软件或资源管理器正占用该目录 → 无通用绕过方法,只能重试或提示用户手动关闭

真正难的不是写循环,是让删操作在各种边界条件下“不崩、不卡、不误伤”。多数人卡在没意识到 recursive_directory_iterator 和 remove() 的协作需要中间缓冲,而不是直觉上的“一边走一边砍”。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

7539

3

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

2023.09.04

1158

7

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

2458

7

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

7027

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2888

6

自建git服务器
自建git服务器

git服务器是目前流行的分布式版本控制系统之一,可以让多人协同开发同一个项目。本专题为大家提供自建git服务器相关的各种文章、以及下载和课程。

2023.07.05

7599

9

git和svn的区别
git和svn的区别

git和svn的区别:1、定义不同;2、模型类型不同;3、存储单元不同;4、是否拥有全局版本号;5、内容完整性不同;6、版本库不同;7、克隆目录速度不同;8、分支不同。php中文网为大家带来了git和svn的相关知识、以及相关文章等内容。

2023.07.06

2100

6

git撤销提交的commit
git撤销提交的commit

Git是一个强大的版本控制系统,它提供了很多功能帮助开发人员有效地管理和控制代码的变更,本专题为大家提供git 撤销提交的commit相关的各种文章内容,供大家免费下载体验。

2023.07.24

1254

5

git提交错误怎么撤回
git提交错误怎么撤回

git提交错误撤回的方法:git reset head^:撤回最后一次提交,恢复到提交前状态。git revert head:创建新提交,内容与之前提交相反。git reset :使用提交的 sha-1 哈希撤回指定提交。交互式舞台区:标记要撤回的特定更改,然后提交,排除已撤回更改。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.09

4917

7

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习