std::filesystem::last_write_time仅获取最后修改时间,不支持创建/访问时间;c++17标准仅强制实现last_write_time,其余为可选,跨平台不可靠。

std::filesystem::last_write_time 只能获取修改时间,不支持创建/访问时间
标准 C++17 std::filesystem 接口在跨平台设计上做了妥协:它只强制要求实现 last_write_time,而 last_access_time 和 creation_time 是可选的(optional)。即使你调用 std::filesystem::last_access_time(path),在 Linux/macOS 上会直接抛出 std::filesystem::filesystem_error(错误码为 not_supported),Windows 上虽可能返回值,但语义也不统一(例如 NTFS 的“创建时间”实际是文件系统级的“首次写入时间”,且不保证微秒精度)。
所以别指望靠标准库一行代码搞定三类时间——它根本没承诺提供。
Linux 下必须用 statx() 系统调用才能拿到纳秒级创建时间
Linux 5.1+ 内核提供了 statx(),是唯一能可靠读取文件“出生时间”(btime)并带纳秒精度的接口。glibc 2.28+ 封装了它,但 C++ 标准库未做绑定,需手写 syscall 或用封装库。
-
statx()返回的struct statx中,stx_btime.tv_sec和stx_btime.tv_nsec组成创建时间(注意:不是所有文件系统都支持,ext4/xfs 支持,btrfs 需挂载选项inode64) - 访问时间(
stx_atime)和修改时间(stx_mtime)也都是纳秒级,比stat()的秒+微秒更精确 - 别用
stat()或fstat():它们最多到微秒(st_atim.tv_usec),且无创建时间字段
示例关键片段:
#include <sys>
#include <linux><p>struct statx stx;
if (statx(AT_FDCWD, "/path/to/file", AT_STATX_SYNC_AS_STAT,
STATX_BTIME | STATX_ATIME | STATX_MTIME, &stx) == 0) {
auto btime_ns = stx.stx_btime.tv_sec * 1000000000LL + stx.stx_btime.tv_nsec;
// btime_ns 是自 Unix epoch 起的纳秒数
}</p></linux></sys>
Windows 下用 GetFileTime + FILE_BASIC_INFO 获取 100ns 精度时间
Windows 文件时间以 100 纳秒为单位(即 0.1 微秒),远超 Linux 的纳秒级。但要注意:Win32 API 的 GetFileTime() 返回的是 UTC 时间,且“创建时间”(ftCreationTime)在重命名、复制等操作中可能被重置;更健壮的方式是用 NT 内核接口 FILE_BASIC_INFO(需 OpenFileById 或 NtQueryInformationFile)。
- 用
GetFileAttributesEx()+WIN32_FILE_ATTRIBUTE_DATA最简单,但仅支持毫秒级(低 16 位被截断) - 必须用
GetFileTime()并将FILETIME转为 64 位整数:其值是从 1601-01-01 UTC 起的 100ns 数,再减去 116444736000000000LL 才能得到 Unix epoch 纳秒值 - 创建时间在某些场景下不可靠(如从 ZIP 解压、网络共享挂载),建议同时检查
dwFileAttributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED等标志辅助判断
跨平台封装时,微秒级精度要主动舍入,别硬凑纳秒
Linux statx 和 Windows FILETIME 的原生精度不同(纳秒 vs 100 纳秒),强行对齐到纳秒反而引入虚假精度。实际工程中,统一转成微秒(std::chrono::microseconds)最稳妥:
- Linux:把
stx_xxx.tv_nsec / 1000向下取整(或四舍五入),避免浮点运算 - Windows:把
FILETIME值除以 10(因 100ns → 1μs),再减去对应 epoch 偏移(11644473600000000LL 微秒) - 永远检查系统调用返回值和 errno/GetLastError();不要假设
creation_time一定存在,fallback 到last_write_time是常见做法
真正难的不是读时间,而是理解每个平台“创建时间”的语义差异——NTFS 的“创建”和 ext4 的“birth”根本不是一回事,连内核文档都写着 “btime is best-effort”。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











