导读:本期聚焦于小伙伴创作的《c++怎么在Linux下获取文件被最后一次读取的精确纳秒级时间戳》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《c++怎么在Linux下获取文件被最后一次读取的精确纳秒级时间戳》有用,将其分享出去将是对创作者最好的鼓励。

在Linux系统中,每个文件的元数据都包含访问时间、修改时间、状态变更时间三类时间戳,其中访问时间就是文件最后一次被读取的时间。要获取纳秒级的精确时间戳,需要借助Linux系统提供的扩展stat结构体实现,传统的stat函数返回的时间戳精度仅到秒级,无法满足纳秒级需求。

c++怎么在Linux下获取文件被最后一次读取的精确纳秒级时间戳

相关结构体和函数说明

Linux系统提供了stat函数用于获取文件元数据,对应的结构体struct stat在默认情况下,时间字段是time_t类型,精度为秒。如果需要纳秒级精度,需要使用扩展的结构体struct statx,该结构体是Linux 4.11之后引入的,支持纳秒级时间戳。

相关的函数原型如下:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <iostream>

// statx函数原型,需要包含对应的头文件
int statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf);

struct statx结构体中,和访问时间相关的字段是stx_atime,它是一个struct statx_timestamp类型的结构体,包含两个字段:

  • tv_sec:时间戳的秒部分,类型为__u64
  • tv_nsec:时间戳的纳秒部分,类型为__u32,取值范围是0到999999999

实现步骤

1. 包含必要的头文件

除了基础的C++头文件,还需要包含系统提供的statx相关头文件,由于部分系统可能需要显式定义特性测试宏才能使用statx,需要在代码开头添加宏定义。

2. 调用statx函数获取文件元数据

调用statx函数时,需要指定要获取的时间戳类型,通过mask参数指定STATX_ATIME即可获取访问时间的相关信息。

3. 提取纳秒级时间戳

从返回的struct statx结构体中提取stx_atimetv_sectv_nsec字段,组合即可得到完整的纳秒级时间戳。

完整代码示例

以下是完整的C++示例代码,实现了获取指定文件最后一次读取的纳秒级时间戳的功能:

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <iostream>
#include <cstdint>

int main() {
    const char *file_path = "test.txt"; // 目标文件路径
    struct statx statx_buf;

    // 调用statx函数,获取文件访问时间信息
    // dirfd为AT_FDCWD表示使用当前工作目录作为相对路径的基准
    // flags设置为0,mask设置为STATX_ATIME表示只获取访问时间
    int ret = statx(AT_FDCWD, file_path, 0, STATX_ATIME, &statx_buf);
    if (ret == -1) {
        perror("statx failed");
        return 1;
    }

    // 检查是否成功获取到访问时间
    if (!(statx_buf.stx_mask & STATX_ATIME)) {
        std::cerr << "Failed to get access time for file: " << file_path << std::endl;
        return 1;
    }

    // 提取秒和纳秒部分
    uint64_t sec = statx_buf.stx_atime.tv_sec;
    uint32_t nsec = statx_buf.stx_atime.tv_nsec;

    std::cout << "File: " << file_path << std::endl;
    std::cout << "Last read timestamp (seconds): " << sec << std::endl;
    std::cout << "Last read timestamp (nanoseconds part): " << nsec << std::endl;
    std::cout << "Full nanosecond-level timestamp: " << sec * 1000000000ULL + nsec << " nanoseconds since epoch" << std::endl;

    return 0;
}

注意事项

  • statx函数是Linux特有的接口,在Linux 4.11及以上版本的内核中才支持,如果系统内核版本较低,可能无法使用该接口,此时可以尝试使用stat函数的扩展版本,部分系统提供了stat64等接口,部分结构体的st_atim字段(struct timespec类型)也包含纳秒级信息,不过需要系统支持。
  • 文件的访问时间更新策略可能受文件系统挂载参数影响,比如部分系统默认挂载时设置了noatime或者relatime参数,可能会导致访问时间不会实时更新,此时获取到的访问时间可能不是最新的读取时间。
  • 编译该程序时,如果是较新的GCC版本,可能不需要额外添加编译选项,如果是旧版本,可能需要添加-D_GNU_SOURCE编译选项,确保statx相关的定义可用。

其他方式说明

如果系统不支持statx函数,还可以尝试使用syscall直接调用系统调用号实现,不过这种方式可移植性更差,示例代码如下:

#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <iostream>
#include <cstdint>

// 定义statx相关的结构体和常量,避免依赖头文件
struct statx_timestamp {
    __u64 tv_sec;
    __u32 tv_nsec;
    __s32 __reserved;
};

struct statx {
    __u32 stx_mask;
    __u32 stx_blksize;
    __u64 stx_attributes;
    __u32 stx_nlink;
    __u32 stx_uid;
    __u32 stx_gid;
    __u16 stx_mode;
    __u16 __spare0[1];
    __u64 stx_ino;
    __u64 stx_size;
    __u64 stx_blocks;
    __u64 stx_attributes_mask;
    struct statx_timestamp stx_atime;
    struct statx_timestamp stx_btime;
    struct statx_timestamp stx_ctime;
    struct statx_timestamp stx_mtime;
    __u32 stx_rdev_major;
    __u32 stx_rdev_minor;
    __u32 stx_dev_major;
    __u32 stx_dev_minor;
    __u64 __spare2[14];
};

#define STATX_ATIME 0x00000002

int main() {
    const char *file_path = "test.txt";
    struct statx statx_buf;

    // 直接调用系统调用,系统调用号为332(不同架构可能不同,x86_64为332)
    int ret = syscall(SYS_statx, AT_FDCWD, file_path, 0, STATX_ATIME, &statx_buf);
    if (ret == -1) {
        perror("syscall statx failed");
        return 1;
    }

    if (!(statx_buf.stx_mask & STATX_ATIME)) {
        std::cerr << "Failed to get access time" << std::endl;
        return 1;
    }

    std::cout << "Last read nanoseconds: " << statx_buf.stx_atime.tv_sec * 1000000000ULL + statx_buf.stx_atime.tv_nsec << std::endl;
    return 0;
}

这种方式不依赖系统头文件中的statx定义,但是需要确认当前系统架构对应的statx系统调用号,可移植性较差,优先推荐使用系统提供的statx函数接口。

C++Linux文件时间戳纳秒级时间戳stat函数修改时间:2026-06-10 19:51:43

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。