std::filesystem::last_write_time 在 Windows 返回 UTC 时间而 Linux/macOS 返回本地时区 time_t,应统一使用 std::chrono::file_clock 避免转换误差;遍历需捕获 permission_denied 异常并跳过;删除前须用 is_regular_file() 判定且避免 remove_all();路径拼接用 path / 运算符防跨平台问题。

std::filesystem::last_write_time 获取文件修改时间不准?
Windows 上 std::filesystem::last_write_time 返回的是 UTC 时间,但本地时区偏移不参与自动转换;Linux/macOS 通常返回本地时钟对应的 time_t(即系统时区下解释的秒数)。直接用 std::chrono::system_clock::now() 减去一周再比对,可能因时区/精度问题漏删或误删。
- 务必统一用
std::chrono::file_clock—— 它是 C++20 为std::filesystem::file_time_type设计的专用时钟,和last_write_time类型一致,避免隐式转换误差 - 不要用
system_clock::now() - 7d去比较,改用file_clock::now() - 7d - 注意:
file_clock在某些旧编译器(如 GCC __cpp_lib_filesystem >= 201703L
遍历目录时 std::filesystem::recursive_directory_iterator 报 permission denied
遇到 std::filesystem::filesystem_error: Permission denied 不代表程序崩溃,而是迭代器默认抛异常。日志目录常含只读子目录(如容器挂载点、符号链接目标不可达),必须主动捕获并跳过。
- 构造
std::filesystem::recursive_directory_iterator时传入std::filesystem::directory_options::skip_permission_denied - 仍需 try/catch 包裹单次
++it或*it操作 —— 因为权限问题可能发生在迭代中途,而非构造时 - 别用
for (auto& entry : iter)范围 for,它内部不处理异常,会直接中止循环
删除前判断是否为普通文件,避免误删目录或符号链接
日志目录里可能混有临时子目录(如 archive/)、.lock 文件、甚至 broken symlink。直接 remove(entry) 可能删掉整个目录树,或对 symlink 本身而非目标生效。
- 先调用
entry.is_regular_file(),排除目录、socket、block device 等 - 对符号链接,
is_regular_file()默认检查目标;若要判断链接本身是否为普通文件,加参数follow_symlinks(false) - 谨慎使用
remove_all()—— 它递归删目录,和“删旧日志”目标不符;只对确认的单个日志文件用remove()
跨平台路径拼接用 std::filesystem::path / 运算符,别手拼字符串
硬编码 "logs/" + filename 在 Windows 下变成 logs\access.log,但 std::filesystem::path 的 / 运算符会自动适配分隔符,且支持 Unicode 路径。
- 路径起点用
std::filesystem::path log_dir = "logs",后续拼接写log_dir / "app.log" - 判断路径是否在目标目录下(防路径穿越),用
entry.path().lexically_relative(log_dir).native().find("..") != 0,但更稳妥是用std::filesystem::proximate()或手动 normalize 后比较根路径 - 删除前建议先
std::cout ,尤其首次运行时——日志名带空格或特殊字符容易出错
最麻烦的其实是时钟对齐:Windows 的 file_clock 和 system_clock 之间没有标准转换函数,得靠 GetSystemTimeAsFileTime 手动桥接;如果项目还要求支持 C++17(无 file_clock),就得退回到 last_write_time().time_since_epoch().count() 做整数秒比对,精度降到秒级。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










