GetFileTime可获取Windows文件最后访问时间,需CreateFile打开文件并转换UTC FILETIME为本地时间;Linux/macOS用stat()读st_atime;C++17 std::filesystem不支持atime,跨平台须自行封装。

Windows 下用 GetFileTime 获取最后访问时间
Windows API 提供了直接读取文件时间戳的能力,GetFileTime 是最常用且可靠的方式。它返回的是 UTC 时间的 FILETIME 结构,需转换为本地可读格式。
关键点在于:必须用 CreateFile 打开文件(哪怕只读),不能传入路径字符串直接调用;而且要指定 FILE_SHARE_READ 避免被其他进程锁住;最后别忘了关闭句柄。
-
GetFileTime的第三个参数是lpLastAccessTime,对应你要的时间 - 返回的
FILETIME是 64 位 100 纳秒单位,需用FileTimeToLocalFileTime+FileTimeToSystemTime转成SYSTEMTIME - 某些 NTFS 卷默认禁用最后访问时间更新(出于性能考虑),此时该字段可能长期不更新——不是代码问题,是系统策略
Linux/macOS 下用 stat 查 st_atime
POSIX 系统统一通过 stat() 系统调用获取文件元信息,其中 st_atime 字段就是最后访问时间(access time)。
注意:st_atime 是 time_t 类型(秒级时间戳),如果需要微秒精度,得看 st_atim.tv_nsec(POSIX.1-2008 起支持),但 glibc 2.2+ 和较新内核才稳定提供。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 调用前确保路径存在且有读权限,否则
stat()返回 -1,errno设为ENOENT或EACCES - 某些挂载选项(如
noatime或relatime)会抑制st_atime更新,这是内核行为,程序无法绕过 - 不要用
ctime(即st_ctime)替代——那是状态变更时间(如权限修改、硬链接数变化),不是访问时间
C++17 std::filesystem::last_write_time 为什么不能用?
std::filesystem::last_write_time 只暴露了修改时间(mtime),C++17 标准没定义获取访问时间(atime)的接口。别试图 cast 或 reinterpret —— 没有标准保证底层结构兼容。
部分编译器(如 MSVC)在 Windows 上可能让 last_write_time 返回近似值,但这是实现细节,不可移植;GCC/libstdc++ 在 Linux 下则严格只映射 st_mtime。
- 想跨平台获取
atime,只能自己封装stat/GetFileTime - 别依赖
std::filesystem::file_time_type的内部表示——它甚至不一定对应系统原生时间类型 - 若仅需判断“是否比某时间新”,可用
stat或GetFileTime后直接比较time_t或FILETIME值,避免转换开销
时区与精度陷阱
最后访问时间本身不带时区信息,但显示时容易误以为是本地时间。Windows 的 FILETIME 是 UTC,Linux 的 st_atime 也是 UTC(尽管 ctime(3) 默认按本地时区打印)。
真正容易出错的是精度丢失:FILETIME 是 100 纳秒,time_t 是秒,struct stat 的纳秒字段名在不同系统上不一致(st_atim.tv_nsec vs st_atimespec.tv_nsec),宏 _GNU_SOURCE 或 _DARWIN_BETTER_REALTIME 可能影响可见性。
- 跨平台代码里,建议统一用秒级时间戳做比较,避免纳秒字段条件编译
- 调试时用
ls -lu(Linux)或dir(Windows)验证结果是否合理,比代码更可信 - 如果文件刚被打开又立刻查
atime,可能还没刷到磁盘——尤其启用了relatime的 ext4 文件系统

















