系统编程手册 第十五章 - DDL-Killer/The-road-of-Linxu-Group2024 GitHub Wiki

获取文件信息:stat()

系统调用stat()、lstat()和fstat(),可获取与文件有关的信息,其中大部分提取自文件i节点

  • #include<sys/stat.h>
  • int stat(const char *pathname,struct stat *statbuf); 返回所命名文件的相关信息
  • int lstat(const char *pathname,struct stat *statbuf); 如果文件属于符号链接,那么所返回的信息针对的是符号链接本身
  • int fstat(int fd,struct stat *statbuf); 返回由某个打开文件描述符所指代文件的相关信息
  • 系统调用stat()和lstat()无需对所操作的文件本身拥有任何权限,但需要对pathname的父目录要有执行(搜索)权限
  • 上述所有系统调用都会在缓冲区中返回一个由statbuf指向的stat结构

设备ID和i节点号

  • st_dev字段标识文件所驻留的设备
  • st_ino字段则包含文件的i节点号
  • dev_t类型记录了设备的主、辅ID
  • 如果针对设备的i节点,那么st_rdev字段则包含设备的主、辅ID
  • 利用宏major(),minor()可以提取dev_t值的主辅ID,在linux系统上<sys/types.h>

文件所有权

  • st_uid标识文件的用户ID
  • st_gid标识文件的组ID

链接数

  • st_nlink字段包含了指向文件的链接数

文件类型和权限

  • st_mode字段含有位掩码,起标识文件类型和指定文件权限的双重作用
  • [][][][U][G][T] [R][W][X] [R][W][X] [R][W][X] (权限) (用户) (组) (其他)
  • 与常量S_IFMT相与(&),可以析取文件类型
  • st_mode字段的低12位定义了文件权限,最低9位表示文件属主、属组以及其他用户的读写执行权限

文件大小、已分配块以及最优I/O块大小

  • st_size:
    1. 常规文件,文件字节数
    2. 符号链接,链接所指路径名长度,以字节为单位
    3. 共享内存对象,对象的大小
  • st_block字段表示分配给文件的总块数,块大小为512字节,包含为指针块所分配的空间,记录了实际分配给文件的磁盘块数量
  • 如果文件内含空洞,该值将小于从相应文件字节数字段的值
  • st_blksize指的是针对文件系统上文件进行I/O操作的最优块大小,一般来说返回值是4096

文件时间戳

  • st_atime,st-mtime,st-ctime分别记录文件上次访问时间、上次修改时间、文件状态发生改变时间

文件时间戳

使用utime()和utimes()来改变文件时间戳

  • #include<utime.h> int utime(const char *pathname,const struct utimbuf *buf); return 0;
  • 参数pathname用来标识欲修改时间的文件,参数buf可以是NULL,也可以是指向utimbuf结构的指针
  • struct utimbuf{time_t actime; time_t modtime};
  • 运作方式
    1. buf为NULL,将文件上次访问和修改时间同时置为当前时间,此时进程需要特权级别或者有效用户id与该文件的用户id相匹配且有写权限
    2. buf为指针,使用该结构的相应字段去更新文件的上次访问和修改时间,此时进程要么特权级别,要么进程有效用户id必须匹配文件用户id(写权限不够)
  • 为更改文件时间戳中的一项,可以先利用stat()来获取两个时间,并使用其中之一来初始化utimbuf结构,然后再将另一时间设置为期望值
  • 还有utimes(),可以以微秒级别来指定时间
  • futimes()和lutimes() 屏幕截图_20250528_234347
    • 调用futimes()时,使用打开文件描述符fd来指定文件
    • 调用lutimes()时,使用路径名来指定文件

使用utimensat()和futimens()改变文件时间戳

  • 优点
    1. 可按纳秒级精度设置时间戳
    2. 可独立设置某一时间戳
    3. 可独立将任一时间戳置为当前时间
  • utimensat()
    图片
  • times[0]是新的访问时间,times[1]是新的修改时间
  • futimes()
⚠️ **GitHub.com Fallback** ⚠️