使用 std::filesystem::last_write_time 读取文件时间戳需注意:Windows 返回 UTC 的 100 纳秒精度 FILETIME,Linux 返回秒或纳秒级 time_t(时区依赖实现);应统一转为 UTC time_point 再格式化,避免隐式时区转换和精度截断。

用 std::filesystem::last_write_time 读取文件时间戳要小心时区和精度
Windows 和 Linux 对 last_write_time 的底层表示不同:Windows 返回的是 FILETIME(100 纳秒精度,UTC),而 POSIX 系统通常返回 time_t(秒或纳秒级,本地时区或 UTC 取决于实现)。直接转成字符串容易出现时间偏移或截断。
- 别用
std::chrono::system_clock::to_time_t直接转 —— 它隐式做本地时区转换,跨平台行为不一致 - 推荐统一转为 UTC 的
std::chrono::time_point<:chrono::system_clock></:chrono::system_clock>,再用std::format(C++20)或std::put_time+gmtime_r/_gmtime64_s格式化 - 注意 C++17 不支持
std::filesystem::last_write_time返回纳秒级精度,Windows 上默认只到 100ns,Linux 可能是 1s 或 1ns,实际取到的值可能比你预期的“更粗”
拼接新文件名时,std::format 比 std::ostringstream 更安全
时间戳转字符串常要补零、对齐、加下划线,手拼容易漏斜杠、混用路径分隔符,或在 Windows 上把 / 写进文件名导致失败。
- 用
std::format("{:%Y%m%d_%H%M%S}_{:03d}", tp, ms)一次性生成带毫秒的标准化前缀,比手动ss 少出错 - 拼路径必须用
std::filesystem::path构造,比如std::filesystem::path(old_path).parent_path() / new_name,避免硬写"./out/" + name - 文件名里禁用
:、*、?、"、、<code>>、|(Windows),std::format不会自动过滤,得自己 replace 或提前校验
批量重命名遇到 std::filesystem::rename 失败的常见原因
不是所有失败都报 “Access denied”——有些静默覆盖、有些因目标已存在而跳过、有些因跨分区失败但没抛异常。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 务必检查返回值:
if (!std::filesystem::rename(old_p, new_p))不够,得捕获std::filesystem::filesystem_error并看.code().value() - 目标路径已存在时,
rename默认失败(不会覆盖),得先remove或用std::filesystem::copy_file(..., std::filesystem::copy_options::overwrite_existing)+remove模拟 - 跨磁盘(如 C:\ → D:\)在 Windows 上不支持原子 rename,必须 copy + delete;Linux 同文件系统才原子,否则也 fallback
Windows 下中文路径用 std::filesystem::u8path 而非 std::string
直接传 UTF-8 字符串给 std::filesystem::path 构造函数,在 MinGW 或 MSVC 低版本里可能被当 ANSI 解码,导致路径乱码或找不到文件。
立即学习“C++免费学习笔记(深入)”;
- 读目录列表时,用
std::filesystem::directory_iterator返回的path原生支持 UTF-8,别转成string()再处理 - 如果输入路径来自用户命令行参数,MSVC 需调用
GetCommandLineW+WideCharToMultiByte(CP_UTF8);MinGW 可直接用argv,但得确保编译时加-finput-charset=UTF-8 - 日志打印路径时,用
p.u8string()而非p.string(),否则中文在控制台显示为问号


















