应使用 try/catch 包裹迭代器初始化和递增操作,配合 directory_options::skip_permission_denied 和手动 while 循环遍历,禁用符号链接跟踪以避免崩溃;查找文件时优先用 is_regular_file() 和 extension() 判断,权限修改前需捕获 filesystem_error。
直接用 std::filesystem::recursive_directory_iterator 遍历目录时,最常见崩溃原因是底层路径不可访问(比如权限不足、符号链接循环、挂载点失效),而默认构造器不捕获异常。必须显式处理 std::filesystem::filesystem_error。
for (auto& entry : std::filesystem::recursive_directory_iterator(path))—— 这会在首次 ++ 时触发访问,异常无法被 for 循环捕获
++iter 前检查 iter != std::filesystem::end(iter)
std::filesystem::directory_options::skip_permission_denied 可跳过无权读取的子目录,但注意:这仅影响「进入子目录」,不抑制对当前项元数据的读取失败不能依赖 entry.path().filename() 粗暴字符串匹配,因为大小写敏感性、编码、隐藏文件属性都可能出错;更可靠的是组合 entry.is_regular_file() 和 entry.path().extension() 判断。
== 而非 string::find:例如 entry.path().extension() == ".log",因为 .extension() 返回的是带点的 std::filesystem::path,不是裸字符串entry.path().filename() == "config.ini",注意它区分大小写(Windows 下通常不敏感,但标准行为是敏感)std::ranges::transform + std::tolower 处理 entry.path().filename().string(),但注意 locale 安全性,生产环境建议用 ICU 或平台 APIentry.status() —— 它可能触发额外系统调用;优先用 entry.is_regular_file() / entry.is_directory(),它们复用已缓存的状态std::filesystem::permissions() 在 Windows 上只模拟 Unix 权限位(通过 ACL 子集),实际效果受限;Linux/macOS 下才真正映射到 chmod。直接设 owner_write 可能被静默忽略。
auto old_perms = std::filesystem::status(path).permissions(),再按位操作,避免覆盖执行位等意外状态std::filesystem::perms::owner_write | std::filesystem::perms::group_write | std::filesystem::perms::others_write,然后 & ~ 写权限位;但注意:这等价于设置只读属性,而非 Unix 式 chmodstd::filesystem::permissions() 对目录生效后,新创建文件会继承父目录默认权限(umask 影响),但已有子项不受影响;要真正递归改,得自己遍历并逐个调用std::filesystem::permissions() 抛 std::filesystem::filesystem_error,错误码可能是 std::errc::operation_not_permitted(Windows 管理员权限缺失)或 std::errc::read_only
_file_system(挂载为 ro)默认情况下 recursive_directory_iterator 会跟随符号链接进入目标目录,导致重复遍历、无限循环甚至栈溢出。除非你明确需要解析软链内容,否则必须关掉。
std::filesystem::directory_options::none:这是最安全的默认选项,完全不跟踪 symlinkstd::filesystem::directory_options::skip_permission_denied | std::filesystem::directory_options::follow_directory_symlink 是错的——follow_directory_symlink 正是你要禁用的行为entry.is_symlink(),它不触发访问,开销极低;可据此做白名单式放行(例如只允许进入特定可信路径下的 symlink)std::filesystem::directory_options::skip_permission_denied,整体耗时下降明显void find_and_chmod_ro(const std::filesystem::path& root, const std::string& ext) {
std::error_code ec;
for (std::filesystem::recursive_directory_iterator iter(root, std::filesystem::directory_options::skip_permission_denied, ec), end; iter != end && !ec; ++iter) {
if (ec) break;
auto& entry = *iter;
if (entry.is_regular_file() && entry.path().extension() == ext) {
try {
std::filesystem::permissions(entry.path(),
std::filesystem::perms::owner_read | std::filesystem::perms::group_read | std::filesystem::perms::others_read,
std::filesystem::perm_options::replace);
} catch (const std::filesystem::filesystem_error& e) {
// 忽略权限修改失败,继续下一个
}
}
}
}
Windows 下测试时记得以管理员身份运行,否则对 Program Files 类路径的 permissions() 调用大概率失败;Linux 下则要注意 umask 是否干扰最终权限位。
# linux
# windows
# 编码
# mac
# 栈
# unix
# c++
# macos
# win
# cos
# String
# for
# while
# try
# catch
# Filesystem
# auto
# 字符串
# 递归
# 循环
# 继承
# transform
# 遍历
# 的是
# 扩展名
# 迭代
# 而非
# 跳过
# 这是
# 也不
# 首次
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
Win10如何优化内存使用_Win10内存优化技巧【攻略】
C++ STL算法库怎么用?C++常用算法函数(sort, find)教程【效率提升】
Win11如何设置环境变量 Win11添加和修改系统与用户变量【教程】
Win11怎么开启上帝模式_创建Windows 11 God Mode全能文件夹【技巧】
C++中引用和指针有什么区别?(代码说明)
如何使用Golang实现文件追加操作_向已有文件追加数据
C++中的constexpr和const有什么区别?(编译期常量)
如何在Golang中实现文件下载_Golang文件传输与内容类型处理方法
Win11怎么设置默认邮件客户端 Win11修改Mail应用关联【教程】
Windows怎样关闭开始菜单推荐广告_Windows关闭开始菜单推荐设置【步骤】
如何使用Golang实现多重错误处理_Golangerror组合与判断方法
php内存溢出怎么排查_php内存限制调试与优化方法【说明】
Windows10系统服务优化指南_Win10禁用不必要服务提升性能
PHP 中如何在函数内持久化修改引用变量的指向
Win11如何设置系统语言_Win11系统语言切换教程【攻略】
VSC怎么创建PHP项目_从零开始搭建项目的步骤【操作】
Mac怎么开启“任何来源”_Mac安装未签名应用的设置方法【解决】
Win11 explorer.exe频繁崩溃_修复Win11资源管理器无限重启【步骤】
Python迭代器生成器进阶教程_节省内存与懒加载实战
Python与OpenAI接口集成实战_生成式AI应用场景解析
如何使用Golang table-driven fuzz测试_多数据随机化发现缺陷
Windows服务无法启动错误1067是什么_进程意外终止的解决方法
Windows10系统怎么查看运行时间_Win10 CPU正常运行时间查询
Win11怎么更改管理员名字 Win11修改账户名称详细步骤【教程】
Win11怎么关闭粘滞键_彻底禁用Windows 11连按Shift粘滞键【步骤】
Linux怎么查找死循环进程_Linux系统负载分析与进程彻底结束【教程】
Python包结构设计_大型项目组织解析【指导】
如何使用Golang实现RPC序列化与反序列化_Golang RPC数据编码与解码方法
Python高性能计算项目教程_NumPyCythonGPU并行加速
如何在Golang中处理模块冲突_解决依赖版本不兼容问题
C++如何编写函数模板?(泛型编程入门)
如何正确访问 Laravel 模型或对象的属性而非调用不存在的方法
如何在 Go 项目开发中正确处理本地包导入与远程模块路径的一致性问题
Win11怎么关闭自动更新 Win11永久关闭系统更新的有效方法【技巧】
c++协程和线程的区别 c++异步编程模型对比【核心】
MAC怎么用连续互通相机里的“桌上视角”_MAC在视频通话中同时展示人脸和桌面
Win11怎么开启空间音效_Windows11耳机杜比音效与Sonic设置
如何在Golang中实现邮件发送功能_Golang SMTP发送与错误处理示例
电脑无法识别U盘怎么办 Windows磁盘管理与驱动更新修复识别问题【解决】
Win10怎么关闭自动更新错误弹窗_Win10策略屏蔽失败提示减少干扰【防护】
Win11怎么关闭自动维护 Win11禁用系统自动维护功能【优化】
Python文件操作优化_大文件与流处理解析【教程】
如何从 Go 的 map[string]interface{} 中安全获取值
Win10系统怎么查看显卡温度_Win10任务管理器GPU温度
Mac如何备份到iCloud_Mac桌面与文稿文件夹云同步【设置】
Windows11如何设置专注助手_Windows11专注助手使用攻略【技巧】
Windows10如何更改鼠标灵敏度_Win10鼠标属性指针选项调节
Python与Docker容器化部署实战_镜像构建与CI/CD流程
如何高效识别并拦截拼接式恶意域名 spam
Windows 10自带杀毒软件在哪_Windows 10打开和使用Windows安全中心
2026-01-01
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。