std::filesystem::last_write_time是获取文件最后修改时间的首选方法,返回file_time_type类型,需转为system_clock::time_point才能格式化输出,且必须启用C++17及以上标准。

std::filesystem::last_write_time 获取修改时间最直接
想拿文件最后修改时间,std::filesystem::last_write_time 是首选,它返回 std::filesystem::file_time_type,本质是高精度时钟点(通常对应系统 FAT/NTFS/ext4 的 mtime)。别试图用 status() 解包时间戳——它不存时间信息,只管权限、类型、存在性。
常见错误:调用 std::filesystem::status("path").permissions() 后以为能顺手拿到时间,结果编译失败或返回随机值。时间戳必须走专用函数。
- 必须开启 C++17 或更高标准(
-std=c++17) - 路径需为绝对路径或确保当前工作目录正确,相对路径出错时不会报“文件不存在”,而是抛
std::filesystem::filesystem_error - 返回值不能直接 cout,要先转成
std::chrono::system_clock::time_point才能格式化输出
auto ftime = std::filesystem::last_write_time("config.json");
auto sctp = std::chrono::clock_cast<std::chrono::system_clock>(ftime);
std::cout << std::put_time(std::localtime(&std::chrono::system_clock::to_time_t(sctp)), "%F %T");
std::filesystem::status 仅用于判断文件元信息,不是时间接口
std::filesystem::status 的作用是快速获取文件是否存在、是否为目录、是否可执行等,底层调用 stat() 系统调用但**不缓存也不暴露其中的 st_mtime 字段**。它的返回值 std::filesystem::file_status 没有公开时间访问方法。
典型误用场景:在循环里反复调用 status() 检查文件变化,却期望从中提取时间做轮询对比——这既低效又不可靠,应改用 last_write_time 配合 file_time_type::operator!= 比较。
立即学习“C++免费学习笔记(深入)”;
-
status()可能触发 symlink 解析(取决于重载版本),若路径含软链且目标不存在,会抛异常;而last_write_time对 dangling symlink 默认失败 - 若只需判断文件是否存在且非目录,
is_regular_file(status(path))比exists()+is_directory()少一次系统调用
跨平台时间精度差异必须手动处理
Windows NTFS 默认提供 100ns 精度,Linux ext4 通常是 1s(老内核)或 1ns(带 CONFIG_FS_EXT4_USE_CREDITS),但 std::filesystem::file_time_type 在各 STL 实现中映射不同:libstdc++ 用 __gnu_cxx::__static_assert 保证与 system_clock 兼容,libc++ 则可能截断纳秒位。直接比较两个文件的 last_write_time 结果,在某些环境下可能因舍入导致“本该相等却判为不等”。
- 如需稳定比较,统一转成
std::chrono::seconds再比:auto sec_a = time_a.time_since_epoch() / 1s; - 写日志或 UI 显示时,优先用
std::format("{:%F %T}", sctp)(C++20),避免localtime的线程不安全问题 - 注意:
last_write_time不等于“创建时间”——Windows 有creation_time(需 WinAPI),Linux 一般无可靠 birth time
权限不足或符号链接失效时的错误处理要点
last_write_time 和 status 都会在权限不足(如只读挂载)、路径不存在、symlink 目标失效时抛 std::filesystem::filesystem_error。但两者的 errno 映射不同:last_write_time 在 Linux 上常映射 ENOENT 或 EACCES,而 status 对 dangling symlink 可能返回 ENOTDIR。
- 不要用
try/catch包裹单次调用就完事,生产代码应预检:先exists(),再is_regular_file(),最后取时间 - 对用户传入路径,建议用
std::filesystem::weakly_canonical规范化,避免../导致权限检查绕过 - 捕获异常后,
e.code().value()比e.what()更适合做分支逻辑(例如区分EPERM和ESTALE)
真正麻烦的是 NFS 或 FUSE 文件系统——last_write_time 可能返回陈旧值,且无法通过 STL 接口感知缓存状态。这种场景下,得退回到 stat() 系统调用并检查 st_ctime 和 st_mtim.tv_nsec 原始字段。


















