RemoveDirectory仅删除空目录,需先递归删除子项再调用;跨平台推荐C++17 std::filesystem::remove_all,但需处理文件占用、权限及路径安全问题。

Windows 下用 RemoveDirectory 只能删空目录
直接调用 RemoveDirectory(来自 Windows.h)时,如果目录下有文件或子目录,函数会失败并返回 false,GetLastError() 返回 ERROR_DIR_NOT_EMPTY。这不是 bug,是设计如此——它对标的是 POSIX 的 rmdir(),只处理空目录。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 先递归遍历目录,用
FindFirstFile/FindNextFile枚举所有项 - 对每个子项:是文件就用
DeleteFile;是目录就递归调用删除逻辑 - 所有子项清空后,再用
RemoveDirectory删除目标目录本身 - 注意跳过
"."和".."目录项,否则会无限递归
Linux/macOS 用 std::filesystem::remove_all 最省事
C++17 起, 是跨平台的可靠选择。std::filesystem::remove_all 原生支持递归删除非空目录,无需手动遍历。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 确保编译器支持 C++17(如 g++ 加
-std=c++17,MSVC 默认开启) - 链接时注意:Linux 下可能需加
-lstdc++fs(GCC 早期版本),Clang 通常不需要 - 调用前用
std::filesystem::exists和std::filesystem::is_directory预检,避免误删文件 - 异常处理不能少:
remove_all抛std::filesystem::filesystem_error,比如权限不足或路径不存在
跨平台兼容写法要避开 system("rm -rf") 和 system("rd /s/q")
用 system() 调外壳命令看似简单,但隐患极多:路径含空格或特殊字符会崩、不同 shell 解析行为不一、无错误粒度控制、Windows/Linux 权限模型差异导致静默失败。
更稳妥的跨平台路径处理方式:
- 优先走
std::filesystem(C++17),它是标准方案,语义清晰,错误可捕获 - 若必须用旧标准(C++11/14),Windows 用
SHFileOperation(带 UI 确认,适合 GUI 场景),Linux 用ftw()或自己写opendir/readdir循环 - 绝对不要拼接字符串构造 shell 命令,尤其当路径来自用户输入时——这是典型注入风险点
std::filesystem::remove_all 在 Windows 上删不了正在使用的文件
即使目录为空,只要其中某个文件被其他进程打开(例如日志文件被记事本打开),remove_all 就会抛异常,错误码通常是 ACCESS_DENIED 或 PROCESS_CANNOT_ACCESS_FILE。
这种场景无法靠重试绕过,只能提前干预:
- 删除前尝试用
CreateFile(Windows)或open(..., O_RDONLY | O_NONBLOCK)(POSIX)检查文件是否可独占访问 - 对关键目录,考虑改用移动到临时位置 + 异步清理(如重命名为
.to_delete_XXXX后由守护线程定时扫) - 日志类目录建议设置文件打开标志为
FILE_SHARE_DELETE(Windows)或使用O_TMPFILE(Linux),让删除更“柔软”











