windows下getfiletime获取最后访问时间需先用createfile打开文件,调用后得到utc格式filetime,再经filetimetolocalfiletime和filetimetosystemtime转换为本地systemtime结构,方可提取年月日时分秒输出。

Windows下用 GetFileTime 获取最后访问时间
在 Windows 平台,GetFileTime 是最直接的方式,但它返回的是 UTC 时间的 FILETIME 结构(64 位 100 纳秒计数),不是本地时间或可读字符串。容易误以为调用后就能直接打印——其实必须先转成 SYSTEMTIME,再格式化。
关键步骤:
- 用
CreateFile以GENERIC_READ打开文件(注意:不能用FILE_ATTRIBUTE_NORMAL替代句柄) - 调用
GetFileTime,传入句柄,接收lpLastAccessTime参数 - 用
FileTimeToLocalFileTime+FileTimeToSystemTime转为本地SYSTEMTIME -
SYSTEMTIME的wYear、wMonth等字段才是整数年月日,别直接 cout 输出结构体
示例片段:
FILETIME ft;
if (GetFileTime(hFile, nullptr, &ft, nullptr)) {
SYSTEMTIME st;
FileTimeToLocalFileTime(&ft, &ft);
FileTimeToSystemTime(&ft, &st);
printf("%04d-%02d-%02d %02d:%02d:%02d",
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond);
}
Linux/macOS 下用 stat 查 st_atime
stat 系统调用是 POSIX 标准方案,但要注意:st_atime 字段默认只在文件被读取且挂载时未加 noatime 才更新。很多现代 Linux 发行版默认启用 noatime,导致 st_atime 停滞甚至为 0。
检查是否生效:
- 运行
mount | grep "noatime",若对应分区有noatime,st_atime就不可信 - 临时关闭需 remount:
sudo mount -o remount,relatime /path(relatime是较平衡的替代) -
st_atime是time_t类型(秒级),如需毫秒精度得看st_atim.tv_nsec(POSIX.1-2008,Linux ≥ 2.5.48 支持)
简单读取:
struct stat sb;
if (stat("file.txt", &sb) == 0) {
char buf[64];
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&sb.st_atime));
puts(buf);
}
C++17 std::filesystem::last_write_time 为什么没有 last_access_time
std::filesystem 标准库目前(C++20 仍未加入)只定义了 last_write_time 和 last_status_change_time,**没有提供标准接口读取最后访问时间**。这是有意为之的设计取舍:因为 atime 在多数场景下既低效又不可靠(尤其 noatime 普遍启用后)。
所以别写 fs::last_access_time(path) —— 编译就报错。跨平台项目若真需要 atime,只能:
- Windows 走
GetFileTime - Linux/macOS 走
stat,并主动检查st_atime是否为 0 或明显过期 - 加一层编译宏判断:
#ifdef _WIN32/#else
最后访问时间的实际意义很弱,别当成“用户打开过”的证据
操作系统层面的 atime 更新粒度粗、易被禁用、受缓存影响大。比如 cat file.txt 可能不触发更新(页缓存命中),而 dd if=file.txt of=/dev/null 却会。更别说编辑器预加载、IDE 全局索引、杀毒软件扫描等后台行为都会污染它。
如果业务逻辑真依赖“用户最近一次查看”,应该自己维护一个时间戳文件或数据库记录,而不是信任系统 atime。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











