不能,std::filesystem::status只返回文件类型和权限位,不包含时间信息;获取时间戳须用last_write_time等专用函数,并注意file_time_type到系统时间的显式转换。

std::filesystem::status 能否直接读取文件时间戳?
不能。std::filesystem::status 只返回文件类型(如 regular、directory)和权限位(permissions),不包含任何时间信息。它底层调用的是类似 stat() 系统调用的 st_mode 字段,和 st_mtime/st_atime 无关。
想拿时间戳,必须用 std::filesystem::last_write_time、std::filesystem::last_access_time 或 std::filesystem::creation_time(后者在 POSIX 上通常未实现,返回 epoch)。
获取 last_write_time 的正确姿势与常见报错
直接调用 std::filesystem::last_write_time(path) 最容易踩两个坑:路径不存在、权限不足。
- 若
path不存在或不可访问,抛出std::filesystem::filesystem_error,不是std::exception,catch 要写全名 - 即使路径存在,若只是“可读”但无执行权限(比如目录无 x 权限),某些系统(如 Linux)会拒绝遍历,导致失败
- 返回值是
std::filesystem::file_time_type,不是time_t或std::chrono::system_clock::time_point,不能直接传给std::ctime
安全写法示例:
立即学习“C++免费学习笔记(深入)”;
try {
auto ft = std::filesystem::last_write_time(p);
auto sctp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(
ft - std::filesystem::file_time_type::clock::now() + std::chrono::system_clock::now()
);
std::time_t ctt = std::chrono::system_clock::to_time_t(sctp);
std::cout << std::ctime(&ctt);
} catch (const std::filesystem::filesystem_error& e) {
std::cerr << "failed: " << e.what() << "\n";
}跨平台时间转换为什么总差 8 小时?
因为 std::filesystem::file_time_type 是以 UTC 为基准的,而 std::ctime 输出的是本地时区时间 —— 差值就是你的时区偏移(比如东八区就是 +8h)。这不是 bug,是设计如此。
如果你需要 UTC 时间字符串,别用 std::ctime,改用 std::put_time 配合 std::gmtime:
auto sctp = std::chrono::time_point_cast<std::chrono::seconds>(ft); std::time_t t = sctp.time_since_epoch().count(); std::cout << std::put_time(std::gmtime(&t), "%Y-%m-%d %H:%M:%S UTC\n");
注意:std::gmtime 返回的是静态缓冲区指针,多线程下要加锁或改用 std::gmtime_r(POSIX)或 std::gmtime_s(MSVC)。
std::filesystem::status 和 std::filesystem::symlink_status 的区别在哪?
关键在符号链接(symlink):前者会解引用,返回目标文件的状态;后者只读链接本身的状态(比如链接文件的权限、大小、创建时间等)。
典型误用场景:
- 检查某个路径是否为目录时用了
status,结果路径是个指向目录的 symlink,它仍返回is_directory == true—— 这可能不是你想要的“它本身是不是目录” - 想确认一个 symlink 是否存在且可读,该用
symlink_status,否则status在目标不存在时直接抛异常 - Windows 上
symlink_status对普通文件和目录行为一致;Linux/macOS 下对 symlink 本身能拿到st_size(链接路径长度),但st_mtime是链接自身的修改时间(非目标)
所以判断“这个路径是不是个有效的、未损坏的 symlink”,应该这样写:
try {
auto sb = std::filesystem::symlink_status(p);
if (std::filesystem::is_symlink(sb)) {
// 安全:sb 是 symlink 本身的属性
}
} catch (...) { /* symlink 不存在或权限问题 */ }实际用的时候,status 和 symlink_status 的选择取决于你关心的是“它指向什么”还是“它自己是什么”;而所有时间操作都绕不开 file_time_type 到系统时间的显式转换 —— 这一步漏掉,输出的时间基本都是错的。


















