std::filesystem::last_write_time 返回 std::filesystem::file_time_type 类型;它是基于 file_clock 的时间点,不能直接转 time_t 或 system_clock::time_point,需通过 time_point_cast 或转换函数处理。

std::filesystem::last_write_time 返回的是什么时间类型
它返回 std::filesystem::file_time_type,不是 time_t 或 std::chrono::system_clock::time_point,直接转成秒或字符串会编译失败或结果错乱。
常见错误现象:auto t = fs::last_write_time(p); std::cout —— 输出一串巨大无意义的纳秒数,且时区、历元都不对。
- 必须先用
fs::file_time_type::clock::to_time_t()转成time_t才能进localtime/gmtime - C++20 起支持
fs::file_time_type到sys_time的隐式转换(需#include <chrono></chrono>),但老标准不行 - Windows 上
file_time_type基于 1601 年 1 月 1 日(FILETIME),Linux/macOS 通常映射到system_clock,跨平台别假设其内部表示
获取可读时间字符串的最小安全写法(C++17)
不依赖平台扩展、不抛异常、能处理权限不足或路径不存在的情况。
使用场景:日志记录、UI 显示、配置文件校验等需要“人类可读时间”的地方。
- 先检查文件是否存在:
if (!fs::exists(path)) { /* 处理错误 */ } - 用
try-catch包住last_write_time调用,因为权限不足会抛fs::filesystem_error - 转
time_t后用std::put_time格式化,避免ctime返回静态缓冲区(线程不安全)
try {
auto ftime = fs::last_write_time(path);
auto ctime = fs::file_time_type::clock::to_time_t(ftime);
std::stringstream ss;
ss <h3>为什么 std::filesystem::last_write_time 在 Windows 上有时返回 1601 年</h3><p>这不是 bug,是 Windows FILETIME 的零点(1601-01-01 00:00:00 UTC)。当你看到 <code>1601-01-01 00:00:00</code>,大概率是文件句柄被其他进程独占、或 NTFS 元数据损坏,导致系统无法读取真实时间戳。</p>
- 常见错误现象:对刚创建的临时文件调用后得到 1601 年;或在某些防病毒软件启用时批量出现
- 不要用
==直接比较file_time_type和 “epoch” —— 不同实现的 epoch 可能不同 - 更稳妥的判断方式:
ftime.time_since_epoch().count() == 0(仅当确认该平台用 1601 年为 epoch 时) - 若需强一致性,考虑 fallback 到
GetFileTime(Windows API)或stat(POSIX),但失去跨平台性
性能与线程安全注意事项
每次调用 last_write_time 都触发一次系统调用,频繁轮询大目录会明显拖慢程序。
使用场景:文件监控、热重载、自动备份等需要周期性检查的逻辑。
- 不要在循环里反复调用,缓存结果并加时间窗口(比如 1 秒内重复请求直接返回上次值)
-
std::filesystem函数本身是线程安全的,但多个线程同时访问同一文件的元数据可能触发 OS 层锁争用 - Windows 上 NTFS 的 last_write_time 精度是 100ns,但 FAT32 是 2 秒;Linux ext4 默认 1 纳秒(实际受硬件限制),这些差异会影响“是否变化”的判断逻辑
最易被忽略的一点:last_write_time 不反映文件内容是否真的变了——只改属性、硬链接更新、甚至某些编辑器的原子写入(先写新文件再 rename)都可能导致它不变或突变。真要检测内容变更,得靠 hash 或 size + mtime 组合判断。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











