C/C++ struct stat介绍

目录

前言

struct stat

struct stat 使用

参考

共勉


前言

        本文详细介绍了stat结构体的成员变量,以及使用案例,希望能够帮到您。


struct stat

        struct stat 结构体用于表示文件或者文件系统对象信息的一种结构体的声明,通常在POSIX(Portable Operating System Interface)兼容的系统中使用,如Linux、macOS和许多UNIX变种。        

头文件

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

stat结构体原型(来源Centos 7 man 手册)

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 file system I/O */
               blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
               time_t    st_atime;   /* time of last access */
               time_t    st_mtime;   /* time of last modification */
               time_t    st_ctime;   /* time of last status change */
           };

参数类型参数描述
dev_tst_dev;表示包含该文件的设备ID
ino_tst_ino;inode号,是文件在文件系统中的唯一标识符
mode_tst_mode;文件的类型和权限
nlink_tst_nlink;文件的硬链接数
uid_tst_uid;文件所有者的用户ID
gid_tst_gid;文件所有者的组ID
dev_tst_rdev;特殊设备的设备ID(如果文件是特殊文件)
off_tst_size;文件的大小(以字节为单位)
blksize_tst_blksize;文件系统I/O的块大小
blkcnt_tst_blocks;已分配的512字节块的数量
time_tst_atime;文件或目录最后一次被读取或访问的时间
time_tst_mtime;表示文件或目录的内容最后一次被修改的时间
time_tst_ctime;

表示文件或目录的状态最后一次被修改的时间

以下是一些常用的POSIX宏,用于检查st_mode字段中的文件类型:

功能
S_ISREG(m)检查m是否表示一个普通文件。
S_ISDIR(m)检查m是否表示一个目录。
S_ISCHR(m)检查m是否表示一个字符设备文件。
S_ISBLK(m)检查m是否表示一个块设备文件。
S_ISFIFO(m)或S_ISPIPE(m)检查m是否表示一个FIFO(命名管道)或管道文件。
S_ISLNK(m)检查m是否表示一个符号链接(在UNIX系统上)。
S_ISSOCK(m)检查m是否表示一个套接字(在某些系统上)。

以下是st_mode中定义的标志字段

S_IFMT0170000文件类型位字段的位掩码,
用于提取文件类型(file type)的掩码
文件类型标志码描述
S_IFSOCK0140000套接字
S_IFLNK0120000符号链接
S_IFREG0100000普通文件
S_IFBLK0060000块设备
S_IFDIR0040000目录
S_IFCHR0020000字符设备
S_IFIFO0010000命名管道
设置ID标志码描述
S_ISUID0004000设置用户ID,如果设置了此位,并且文件是可执行的,则运行该文件时,其有效用户ID将变为文件所有者的用户ID。这通常用于允许程序以特定用户的身份运行。
S_ISGID0002000设置组ID,如果设置了此位,并且文件是可执行的目录,则新创建的文件和子目录将继承该目录的组ID,而不是创建者的主组ID。如果文件是普通文件并且是可执行的,则效果与S_ISUID相似,但用于组ID。
S_ISVTX0001000粘滞位
权限掩码标志码描述
S_IRWXU00700文件所有者权限掩码
S_IRUSR00400拥有者有读权限
S_IWUSR00200拥有者有写权限
S_IXUSR00100拥有者有执行权限
S_IRWXG00070组权限掩码
S_IRGRP00040组具有读权限
S_IWGRP00020组具有写权限
S_IXGRP00010组具有执行权限
S_IRWXO00007其他权限掩码
S_IROTH00004其他具有读权限
S_IWOTH00002其他具有写权限
S_IXOTH00001其他具有执行权限

struct stat 使用

int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);

        stat(),fstat(), lstat() 是Unix和类Unix系统中用于获取文件或目录状态信息的函数。这些函数之间的主要区别在于它们获取状态信息的方式以及它们处理符号链接(symbolic links)的方式。执行成功返回0失败返回-1并设置错误码。


stat()
        stat() 函数通过文件或目录的路径名(path)来获取其状态信息。如果路径名是一个符号链接,stat() 会跟随这个链接,返回链接指向的文件或目录的状态信息

fstat()
        fstat() 函数通过已打开的文件描述符(fd)来获取文件的状态信息。这意味着你必须已经使用如 open() 或其他相关函数打开了文件,并获取了文件描述符。fstat() 不会跟随符号链接,因为它直接作用于已打开的文件描述符

lstat()
        lstat() 函数也通过文件或目录的路径名(path)来获取状态信息。但是,与 stat() 不同,如果路径名是一个符号链接,lstat() 会返回符号链接自身的状态信息,而不是链接指向的文件或目录的状态信息。

错误码

错误码描述
EACCES调用进程没有足够的权限来访问路径中的某个目录,或者路径中的某个符号链接没有执行权限。
EBADF错误的文件描述符
EFAULT错误的地址
ELOOP在解析路径时遇到了太多的符号链接。
ENAMETOOLONG路径过长
ENOENT文件或目录不存在
ENOMEM系统无法为请求的操作分配足够的内存空间
ENOTDIR路径名不是一个目录
EOVERFLOW表示值太大无法放入指定类型的变量

下面就用stat()函数来举个例子

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

using namespace std;

int main()
{
    struct stat st;
    stat("./testLog.cc", &st); // 这里的.cc文件

    std::cout << "st.st_dev: " << st.st_dev << std::endl;
    std::cout << "st.st_ino: " << st.st_ino << std::endl;
    std::cout << "st.st_nlink: " << st.st_nlink << std::endl;
    std::cout << "st.st_uid: " << st.st_uid << std::endl;
    std::cout << "st.st_gid: " << st.st_gid << std::endl;
    std::cout << "st.st_size: " << st.st_size << std::endl;
    std::cout << "st.st_atime: " << st.st_atime << std::endl;
    std::cout << "st.st_mtime: " << st.st_mtime << std::endl;
    std::cout << "st.st_ctime: " << st.st_ctime << std::endl;

    switch (st.st_mode & S_IFMT)
    {
    case S_IFSOCK:
        std::cout << "是套接字文件" << std::endl;
        break;
    case S_IFLNK:
        std::cout << "链接文件" << std::endl;
        break;
    case S_IFREG:
        std::cout << "是普通文件" << std::endl;
        break;
    case S_IFBLK:
        std::cout << "是块设备" << std::endl;
        break;
    case S_IFDIR:
        std::cout << "是目录" << std::endl;
        break;
    case S_IFCHR:
        std::cout << "是字符设备" << std::endl;
        break;
    case S_IFIFO:
        std::cout << "是命名管道" << std::endl;
        break;
    }
    return 0;
}


参考

        man手册: man 2 stat

        互联网


共勉

        以上就是我对stat结构体的认识。如果有什么疑问或者问题,欢迎评论区讨论或者私信我。可以的话请帮我点点赞和收藏,谢谢。


感谢阅读

  • 31
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值