用std::filesystem::last_write_time判断日志是否过期一周,需将文件时间转为system_clock时间点再比较:先to_time_t()再from_time_t(),然后与now()差值≥7天(推荐std::chrono::hours(168))。

如何用 std::filesystem::last_write_time 判断日志是否过期一周
核心是把文件修改时间转成可比较的时间点,不能直接拿 file_time_type 和系统当前时间硬比——它们时钟类型不同,强行比较会编译失败或行为未定义。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用
std::filesystem::file_time_type调std::filesystem::last_write_time(path)获取文件时间 - 通过
std::filesystem::file_time_type::clock::to_time_t()转成time_t,再用std::chrono::system_clock::from_time_t()转到系统时钟时间点 - 用
std::chrono::system_clock::now()减去它,判断差值是否 ≥ 7 天(std::chrono::hours(24 * 7)更稳妥,避免闰秒/夏令时干扰)
遍历目录时跳过子目录、只处理 .log 文件的惯用写法
std::filesystem::recursive_directory_iterator 默认递归进子目录,但删日志通常只清当前目录下的日志文件,进子目录反而容易误删或性能变差。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 改用
std::filesystem::directory_iterator(非 recursive) - 对每个
entry先调entry.is_regular_file()排除目录和符号链接 - 用
entry.path().extension() == ".log"过滤,注意 Windows 下大小写不敏感,Linux 下敏感;若需兼容,建议转小写再比 - 别依赖
entry.path().filename().string()做字符串匹配——扩展名可能带多个点(如app.log.20240501),extension()才语义正确
删除前必须检查权限和打开状态,否则 std::filesystem::remove 静默失败
Windows 下如果日志正被进程以独占方式打开(比如还在写入),remove() 直接返回 false;Linux 下可能成功但文件只是“标记删除”,实际空间未释放。用户常以为删了,其实没生效。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 删之前加一层
std::filesystem::status(entry.path()).permissions() & std::filesystem::perms::owner_write检查可写 - 捕获
std::filesystem::filesystem_error异常,检查ec.value():Windows 是5(拒绝访问),Linux 常见16(设备或资源忙) - 对失败项记录日志(含
ec.message()),不要吞掉错误——静默跳过是后续排查黑洞
跨平台路径拼接必须用 std::filesystem::path 构造,别手拼字符串
手写 "logs/" + filename 在 Windows 下变成 logs\app.log,但 \ 在 C++ 字符串里是转义符,实际变成非法路径;Linux 下虽能跑,但代码失去可移植性。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 所有路径操作统一走
std::filesystem::path:比如std::filesystem::path log_dir = "logs"; auto full_path = log_dir / "app.log"; -
/运算符自动适配平台分隔符,log_dir / "sub" / "file.log"安全可靠 - 避免
.string()提前转字符串——尤其在路径含 Unicode 时,.u8string()或直接传path对象给 filesystem 函数更稳
最麻烦的其实是时区和夏令时:last_write_time 是本地时钟,但服务器可能跨时区部署。如果日志按 UTC 命名却用本地时间判断,一周边界就偏了。这点没人提,但线上出过问题。


















