c++17标准库std::Filesystem不支持获取文件创建时间,仅提供last_write_time和last_access_time;创建时间需依赖平台API:windows用GetFileTime,linux/macos无可靠跨平台方案。

std::filesystem::last_write_time 能拿到修改时间,但创建时间在 C++17 里没有标准支持
标准库 std::filesystem 在 C++17 中提供了跨平台的文件属性访问能力,但仅定义了 last_write_time 和 last_access_time,没有 creation_time 的标准化接口。这意味着你用 std::filesystem::last_write_time(path) 可以可靠获取修改时间,但“创建时间”必须依赖平台扩展或系统 API。
常见错误是直接尝试调用不存在的 creation_time() 方法,编译器会报错:no member named 'creation_time' in Namespace 'std::filesystem'。
-
std::filesystem::last_write_time(path)返回std::filesystem::file_time_type,需转换为std::time_t才能用std::ctime等格式化 - windows 下可用
GetFileInformationByHandle提取ftCreationTime;Linux/macOS 没有真正意义上的“创建时间”,st_birthtime(macOS)或st_crtime(某些 Linux 文件系统如 btrfs/xfs)是非标准、不可移植的扩展 - 若项目要求跨平台且必须含创建时间,建议记录写入时的时间戳到元数据文件或数据库,而非依赖文件系统
把 file_time_type 转成可读时间字符串要经过两次转换
std::filesystem::file_time_type 是独立于 std::chrono::system_clock 的时钟类型,不能直接传给 std::gmtime 或 std::localtime。必须先转成 std::time_t,中间需借助 clock_cast(C++20)或手动换算(C++17)。
C++17 下典型做法是:先用 std::filesystem::file_time_type::clock::to_time_t(如果存在),但更稳妥的是通过 std::chrono::system_clock 中转:
立即学习“C++免费学习笔记(深入)”;
auto ft = std::filesystem::last_write_time(path); auto sct = std::chrono::time_point_cast( ft - ft.clock::now() + std::chrono::system_clock::now() ); std::time_t ctime = std::chrono::system_clock::to_time_t(sct);
这段代码容易出错:若文件时间早于 system_clock::now(),可能导致负偏移溢出;更健壮的做法是使用 Boost.Filesystem 或封装平台 API。
Windows 上用 GetFileTime 获取创建/修改/访问时间最直接
Windows API 的 GetFileTime 一次性返回三个时间戳,对应创建(lpCreationTime)、最后访问(lpLastAccessTime)、最后写入(lpLastWriteTime),精度达 100 纳秒,且稳定可用。
- 需先用
CreateFile打开句柄,注意设置FILE_FLAG_BACKUP_SEMANTICS才能打开目录 - 返回的
FILETIME是自 1601-01-01 的 100ns 计数,要用FileTimeToSystemTime或FileTimeToLocalFileTime+FileTimeToSystemTime转成本地可读结构 - 记得关闭句柄,否则泄漏资源;
INVALID_HANDLE_VALUE和GetLastError()是判断失败的关键
不推荐用 FindFirstFile,它只提供最后写入和最后访问时间,且对创建时间的支持在不同 Windows 版本中行为不一致。
Linux 下 st_birthtime 不是 POSIX 标准,别默认它存在
Linux 内核本身不维护“创建时间”,glibc 的 stat 结构体没有 st_birthtime 字段。某些文件系统(如 ext4)虽支持 btrfs ioctl(BTRFS_IOC_FS_INFO) 或 xfs 的 xfs_ioc_fsgeometry_v1,但用户态工具如 stat -c '%w' file 能显示“Birth”只是因为 coreutils 尝试读取扩展属性或特定 ioctl —— 这意味着:
- 同一程序在 ext4 上可能读不到,在 btrfs 上却能读到,行为不可预测
-
statx(2)系统调用(Linux 4.11+)提供了statx.stx_btime,但需手动调用,且 glibc 尚未封装进stat函数 - 即使读到,精度也常被截断为秒级,且部分内核配置会禁用 birthtime 支持
如果你看到某段 C++ 代码在 Linux 上调用了 st.st_birthtime 并成功运行,大概率是它链接了非标准补丁版 glibc,或运行在极少数启用 birthtime 的定制内核上 —— 这类代码不具备部署可靠性。