使用std::filesystem递归搜索文件时访问回收站目录崩溃问题
问题分析与修复
1. 访问回收站目录并崩溃的原因
std::filesystem::recursive_directory_iterator默认会遍历所有子目录,包括Windows系统保护的$Recycle.Bin这类目录。普通用户没有访问其中部分子目录(比如S-1-5-18,对应系统账户)的权限,迭代器访问时会抛出std::filesystem::filesystem_error,直接导致程序崩溃。
2. 代码中的其他关键错误
- 字符串语法错误:
std::string start_path = "C:\\\\\";最后一个反斜杠转义了结束引号,导致字符串未正确闭合,会引发未定义行为。 - 搜索逻辑偏差:当前代码只检查目录的名称,完全忽略了文件,不符合“搜索文件”的核心需求。
- 缺少必要头文件:使用
std::numeric_limits但未包含<limits>头文件,会导致编译失败。 - 未处理权限异常:未给迭代器设置跳过无权限目录的选项,触发权限错误时直接崩溃。
3. 修复后的代码
#include <string> #include <filesystem> #include <iostream> #include <limits> // 必须包含此头文件以使用std::numeric_limits namespace fs = std::filesystem; // 别名简化代码 fs::path find_file_path(const std::string& file_name, const fs::path& search_path) { // 创建迭代器时添加skip_permission_denied选项,跳过无权限访问的目录 for (const auto& entry : fs::recursive_directory_iterator( search_path, fs::directory_options::skip_permission_denied)) { // 检查当前条目是文件,且文件名匹配 if (entry.is_regular_file() && entry.path().filename() == file_name) { return entry.path(); } } return fs::path(); // 未找到返回空路径 } int main() { std::string input_file{}; std::cout << "hello! enter file name here: "; std::cin >> input_file; std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 用原始字符串初始化路径,避免转义错误 const fs::path start_path = R"(C:\)"; fs::path file_path = find_file_path(input_file, start_path); if (!file_path.empty()) { std::cout << "Found file at: " << file_path << '\n'; } else { std::cout << "File not found.\n"; } return 0; }
4. 额外优化建议
- 使用
namespace fs = std::filesystem简化代码,避免重复写冗长的命名空间前缀。 - 添加未找到文件时的提示,提升用户体验。
- 如果需要同时搜索目录和文件,可以去掉
entry.is_regular_file()的判断,根据需求调整。
内容的提问来源于stack exchange,提问作者chrkspln
相关产品推荐
相关产品推荐

