linux C之stat函数

这篇博客主要介绍了Linux C编程中的stat函数,用于获取文件详细信息。内容包括stat函数的作用、函数定义、结构体成员及宏定义的解析,特别提到了st_mtime、st_atime、st_ctime的时间戳转换,并探讨了如何判断文件类型。文章末尾表达了对查找资料繁琐过程的困扰,希望寻求更高效的资料查询方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 之前写过一篇关于stat命令的博客,介绍了stat命令的使用和输出信息表示,今天又见到了stat函数,因为输出原因,准备整理一下。
stat函数介绍

  根据《UNIX环境高级编程》中对于stat函数的解释,stat函数和stat命令一样,都是返回该文件的详细信息。
函数定义为:

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    int stat(const char *pathname, struct stat *buf);

  其中pathname是文件的路径名,支持绝对路径和相对路径,buf是一个结构体保存文件的信息,这个结构体的构造如下:

 struct stat {
               dev_t     st_dev;         /* ID of device containing file */
               ino_t     st_ino;         /* inode number */
               mode_t    st_mode;        /* protection */
               nlink_t   st_nlink;       /* number of hard links */
               uid_t     st_uid;         /* user ID of owner */
               gid_t     st_gid;         /* group ID of owner */
               dev_t     st_rdev;        /* device ID (if special file) */
               off_t     st_size;        /* total size, in bytes */
               blksize_t st_blksize;     /* blocksize for filesystem I/O */
               blkcnt_t  st_blocks;      /* number of 512B blocks allocated */

               /* Since Linux 2.6, the kernel supports nanosecond
                  precision for the following timestamp fields.
                  For the details before Linux 2.6, see NOTES. */

               struct timespec st_atim;  /* time of last access */
               struct timespec st_mtim;  /* time of last modification */
               struct timespec st_ctim;  /* time of last status change */

           #define st_atime st_atim.tv_sec      /* Backward compatibility */
           #define st_mtime st_mtim.tv_sec
           #define st_ctime st_ctim.tv_sec
           };
数据类型变量名实际数据类型输出方式表示含义
mode_tst_modeunsigned int%u文件类型和权限
dev_tst_devlong long int%lu文件的主、次设备信息
dev_tst_rdevlong long int%lu如果是字符设备和块设备会有这个字段
ino_tst_inounsigned long int%luinode编号
nlink_tst_nlinkunsigned long int%lu硬链接的个数
uid_tst_uidunsigned int%uuid编号
git_tst_gidunsigned int%ugid编号
blksize_tst_blksizelong int%ld占用区块的大小,一般和页表大小相同
blkcnt_tst_blockslong int%ld占用几个页表或区块
off_tst_sizelong int%ld文件的大小

  另外,注意结构体中的三个宏定义,本来st_mtime,st_atime,st_ctime三个都是一个timespac的结构体,但是经过宏定义后,直接可以输出,这个如果不细心的话还是很容易搞乱的。

  与之对应的还有几个宏定义,需要了解一下,对于stat结构体中的st_mode,有几个宏定义一颗根据st_mode的值判断打开文件的类型:

函数参数使用返回值类型含义
S_ISREG()st_modeS_ISR EG(st_mode)bool是否为普通文件
S_ISDIR()st_modeS_ISDIR(st_mode)bool是否为目录
S_ISCHR()st_modeS_ISCHR(st_mode)bool是否为字符特殊文件
S_ISBLK()st_modeS_ISBLK(st_mode)bool是否为块文件
S_ISFIFO()st_modeS_ISFIFO(st_mode)bool是否为管道
S_ISLINK()st_modeS_ISLINK(st_mode)bool是否为符号链接
S_ISSOCK()st_modeS_ISSOCK(st_mode)bool是否为套接字
S_TYPEISMQ()&st_modeS_TYPEISMQ(st_mode)bool是否为消息队列
S_TYPEISSEM()&st_modeS_TYPEISSEM(st_mode)bool是否为信号量
S_TYPEISSHM()&st_modeS_TYPEISSHM(st_mode)bool是否为共享内存
  • 数据类型可以在/usr/include/x86_64-linux-gnu/sys/types.h中找到,发现又是
不想看这些条条串串的,可以直接看最后的表格
#ifndef  __mode_t defined
typedef __mode_t mode_t;
#define __mode_t_defined
#endif
  • 根据头文件bits/types.h(/usr/inlcude/x86_64-linux-gnu/bits/types.h)查询,此时找到的是:
# define __STD_TYPE     typedef

__STD_TYPE __DEV_T_TYPE __dev_t;            /* Type of device numbers.  */
__STD_TYPE __UID_T_TYPE __uid_t;            /* Type of user identifications.  */
__STD_TYPE __GID_T_TYPE __gid_t;            /* Type of group identifications.  */
__STD_TYPE __INO_T_TYPE __ino_t;            /* Type of file serial numbers.  */
__STD_TYPE __MODE_T_TYPE __mode_t;          /* Type of file attribute bitmasks.  */
__STD_TYPE __NLINK_T_TYPE __nlink_t;        /* Type of file link counts.  */
__STD_TYPE __OFF_T_TYPE __off_t;            /* Type of file sizes and offsets.  */

//还有很多,自己看吧。
  • typesizes.h中是这么定义的
#define __DEV_T_TYPE        __UQUAD_TYPE
#define __UID_T_TYPE        __U32_TYPE
#define __GID_T_TYPE        __U32_TYPE
#define __INO_T_TYPE        __SYSCALL_ULONG_TYPE
#define __MODE_T_TYPE       __U32_TYPE
#ifdef __x86_64__
# define __NLINK_T_TYPE     __SYSCALL_ULONG_TYPE
# define __FSWORD_T_TYPE    __SYSCALL_SLONG_TYPE
#else
# define __NLINK_T_TYPE     __UWORD_TYPE
# define __FSWORD_T_TYPE    __SWORD_TYPE
#endif
#define __OFF_T_TYPE        __SYSCALL_SLONG_TYPE
  • 绕了一圈又回去了。。。伤脑筋。
    然后对照信息,终于发现定义,基本是这样:
目标数据类型文件sys/types.h文件/bits/types.h文件typesizes.h文件sys/types.h
mode_t__mode_t__MODE_T_TYPE__U32_TYPEunsigned int
dev_t__dev_t__DEV_T_TYPE__UQUAD_TYPE__u_quad_t –> long long int
ino_t__ino_t__INO_T_TYPE__SYSCALL_ULONG_TYPEunsigned long int
nlink_t__nlink_t__NLINK_T_TYPE__SYSCALL_ULONG_TYPEunsigned long int
uid_t__uid_t__UID_T_TYPE__U32_TYPEunsigned int
git_t__git_t__GID_T_TYPE__U32_TYPEunsigned int
blksize_t__blksize_t__BLKSIZE_T_TYPE__SYSCALL_SLONG_TYPElong int
blkcnt_t__blkcnt_t__BLKCNT_T_TYPE__SYSCALL_SLONG_TYPElong int
* 所以查找东西真的很累,有没有人给我推荐一个软件或一种方法*
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值