GetFileTime可获取文件最后访问时间,但NTFS默认禁用更新,需用fsutil启用;返回FILETIME需转换为本地时间;C++17标准库未提供last_access_time因跨平台不可靠。

Windows 下用 GetFileTime 获取最后访问时间
Windows API 提供了直接读取文件时间戳的能力,GetFileTime 是最常用且可靠的方式。它返回三个时间:创建、最后访问、最后写入,其中最后访问时间(access time)对应 lpLastAccessTime 参数。
注意:NTFS 默认会禁用最后访问时间更新(出于性能考虑),所以即使你刚读过文件,lpLastAccessTime 也可能没变。需确认系统策略或手动启用:fsutil behavior set disablelastaccess 0(管理员权限运行)。
实操要点:
-
GetFileTime需要先用CreateFile打开文件,且必须带FILE_READ_ATTRIBUTES权限(不需要GENERIC_READ) - 返回的
FILETIME是 64 位 Windows 时间(100 纳秒精度,从 1601-01-01 起),需用FileTimeToLocalFileTime+FileTimeToSystemTime转成可读结构 - 若只关心秒级时间,可转为
time_t:用FileTimeToSystemTime后填入SYSTEMTIME,再调用SystemTimeToTzSpecificLocalTime和SystemTimeToFileTime反向绕一下,但更简单的是用ULARGE_INTEGER手动换算(减去 116444736000000000LL,除以 10000000)
Linux/macOS 下用 stat 结构体读 st_atime
POSIX 系统通过 stat() 系统调用获取文件元信息,st_atime 字段即最后访问时间,类型是 time_t(秒级 Unix 时间戳)。
立即学习“C++免费学习笔记(深入)”;
常见误区:
使用tbot机器ID身份文件配合tsh CLI,通过Teleport访问控制SSH登录托管主机或执行远程命令。
- 某些文件系统(如 ext4)默认挂载时启用
relatime,只在“上次访问早于修改时间”或“距上次访问超 24 小时”时才更新st_atime,所以它不一定是“真实最近一次读取时间” - 用
stat不需要打开文件,传路径字符串即可;但要注意符号链接行为:stat跟随链接,lstat不跟随 - 若需纳秒精度(如 ext4 +
strictatime),应读st_atim.tv_nsec(注意字段名带m,不是st_atime_nsec)
C++17 std::filesystem::last_write_time 为什么没有 access time?
std::filesystem::last_write_time 存在,但标准库**故意没提供获取 access time 的接口**。C++ 标准委员会认为:st_atime 行为跨平台差异太大(Windows 默认关、Linux 常被挂载选项抑制、macOS HFS+ 甚至不维护该字段),不可靠,不适合作为标准化 API 暴露。
所以你不能写:
std::filesystem::file_time_type at = std::filesystem::last_access_time(p); // 编译错误
替代方案只有:
- Windows:坚持用
GetFileTime - Linux/macOS:用
stat+st_atime - 跨平台封装时,建议加编译期判断(
#ifdef _WIN32/#ifdef __linux__),并明确文档注明“该值可能未更新”
Python 或 shell 脚本里能直接看到,C++ 却要自己折腾?
因为 Python 的 os.stat().st_atime 和 shell 的 stat -c '%x' file 都是对底层 stat 或 GetFileTime 的封装,而 C++ 标准库选择不隐藏这些平台差异——它把“是否值得信任”这个判断权交还给开发者。
真正容易被忽略的一点是:最后访问时间不是审计日志。它不记录谁、何时、以何种方式访问,也不保证原子性更新;仅作粗略参考。如果你需要可靠访问追踪,得用内核模块(如 Linux auditd)、文件系统钩子(Windows MiniFilter)或应用层主动打点。

















