c++oding="utf-8" ?>
std::filesystem::last_write_time 仅返回最后修改时间,无法跨平台获取创建时间;Windows 上 MSVC 16.10+ 提供非标准 creation_time,GCC/Clang 不支持;实际可用的可靠时间戳只有 last_write_time 或 last_access_time。

std::filesystem::last_write_time 不能直接判断“创建时间”
Windows 上 std::filesystem::last_write_time 返回的是最后修改时间,而 std::filesystem::status 或 std::filesystem::symlink_status 在大多数标准库实现(如 libstdc++、libc++)中**根本不暴露创建时间(birth time)**。MSVC 的 std::filesystem 从 VS2019 16.10 起才通过非标准扩展 std::filesystem::creation_time 支持,但 GCC/Clang 仍不支持。所以“一周前创建”在跨平台 C++ 中本质是不可靠的——你真正能用的只有修改时间或访问时间。
实操建议:
- 如果日志写完就不再修改(典型场景),
last_write_time≈ 创建时间,可放心用 - 若日志可能被归档脚本 touch 或重命名,需额外加命名规则约束(例如文件名含
log_20240501) - Linux 下可通过
stat -c '%w' file查看 birth time,但 C++ 标准库不提供对应接口,别硬套
遍历目录并过滤出一周前的文件(含错误处理)
直接用 std::filesystem::recursive_directory_iterator 遍历,但必须捕获异常——比如权限不足的子目录、挂载点断开、符号链接循环,都会抛 std::filesystem::filesystem_error。不 catch 就 crash。
实操建议:
- 用
std::filesystem::directory_options::skip_permission_denied跳过无权读取的目录,避免中断遍历 - 对每个
entry先调用entry.is_regular_file(),跳过目录、socket、设备文件 - 用
std::chrono::system_clock::now() - std::chrono::hours(24 * 7)算截止时间点,注意时区:system_clock是 UTC,但文件时间戳也是 UTC(POSIX)或本地时间(Windows),实际一致
简短示例:
fs::remove
- 文件正被其他进程打开(Windows 尤其严格)→ 错误码
ERROR_SHARING_VIOLATION(Win)或EBUSY(Linux) - 路径太长(Windows MAX_PATH=260)→ 用
\?前缀,但std::filesystem不自动处理,得自己拼 - 只读属性未清除 → 先调用
fs::permissions(path, fs::perms::owner_write, fs::perm_options::add)
实操建议:删之前加日志,输出 path 和 ec.message(),别只写“failed”。
性能与线程安全提醒
std::filesystem 操作全是同步阻塞 IO,遍历万级日志文件可能卡几百毫秒。别在主线程或实时敏感路径里调用。
注意点:
- 所有
std::filesystem函数都不是线程安全的——多个线程同时操作同一路径(如并发删不同文件)没问题,但共享同一个fs::path对象并修改它(如拼接)就有风险 - 频繁调用
last_write_time会触发多次系统调用,可考虑先 collect 所有候选路径再批量处理 - Windows 上
fs::remove_all删除大目录极慢,不如先fs::remove单个文件
真正难的不是写对语法,而是搞清你的日志文件到底有没有可靠的“创建时间”,以及是否允许因某个文件删不掉就中断整个清理流程——这俩问题不提前想清楚,代码跑起来永远在修边角 case。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











