C/C++ struct stat介绍

目录

前言

[struct stat](#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 手册)

cpp 复制代码
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_t | st_dev; | 表示包含该文件的设备ID |
| ino_t | st_ino; | inode号,是文件在文件系统中的唯一标识符 |
| mode_t | st_mode; | 文件的类型和权限 |
| nlink_t | st_nlink; | 文件的硬链接数 |
| uid_t | st_uid; | 文件所有者的用户ID |
| gid_t | st_gid; | 文件所有者的组ID |
| dev_t | st_rdev; | 特殊设备的设备ID(如果文件是特殊文件) |
| off_t | st_size; | 文件的大小(以字节为单位) |
| blksize_t | st_blksize; | 文件系统I/O的块大小 |
| blkcnt_t | st_blocks; | 已分配的512字节块的数量 |
| time_t | st_atime; | 文件或目录最后一次被读取或访问的时间 |
| time_t | st_mtime; | 表示文件或目录的内容 最后一次被修改的时间 |
| time_t | st_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_IFMT | 0170000 | 文件类型位字段的位掩码, 用于提取文件类型(file type)的掩码 |
| 文件类型 | 标志码 | 描述 |
| S_IFSOCK | 0140000 | 套接字 |
| S_IFLNK | 0120000 | 符号链接 |
| S_IFREG | 0100000 | 普通文件 |
| S_IFBLK | 0060000 | 块设备 |
| S_IFDIR | 0040000 | 目录 |
| S_IFCHR | 0020000 | 字符设备 |
| S_IFIFO | 0010000 | 命名管道 |
| | | |
| 设置ID | 标志码 | 描述 |
| S_ISUID | 0004000 | 设置用户ID,如果设置了此位,并且文件是可执行的,则运行该文件时,其有效用户ID将变为文件所有者的用户ID。这通常用于允许程序以特定用户的身份运行。 |
| S_ISGID | 0002000 | 设置组ID,如果设置了此位,并且文件是可执行的目录,则新创建的文件和子目录将继承该目录的组ID,而不是创建者的主组ID。如果文件是普通文件并且是可执行的,则效果与S_ISUID相似,但用于组ID。 |
| S_ISVTX | 0001000 | 粘滞位 |
| | | |
| 权限掩码 | 标志码 | 描述 |
| S_IRWXU | 00700 | 文件所有者权限掩码 |
| S_IRUSR | 00400 | 拥有者有读权限 |
| S_IWUSR | 00200 | 拥有者有写权限 |
| S_IXUSR | 00100 | 拥有者有执行权限 |
| S_IRWXG | 00070 | 组权限掩码 |
| S_IRGRP | 00040 | 组具有读权限 |
| S_IWGRP | 00020 | 组具有写权限 |
| S_IXGRP | 00010 | 组具有执行权限 |
| S_IRWXO | 00007 | 其他权限掩码 |
| S_IROTH | 00004 | 其他具有读权限 |
| S_IWOTH | 00002 | 其他具有写权限 |
| S_IXOTH | 00001 | 其他具有执行权限 |

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()函数来举个例子

cpp 复制代码
#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结构体的认识。如果有什么疑问或者问题,欢迎评论区讨论或者私信我。可以的话请帮我点点赞和收藏,谢谢。


感谢阅读

相关推荐
蜀黍@猿28 分钟前
【C++ 基础】从C到C++有哪些变化
c++
Am心若依旧40929 分钟前
[c++11(二)]Lambda表达式和Function包装器及bind函数
开发语言·c++
明月看潮生31 分钟前
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
开发语言·青少年编程·单元测试·编程与数学·goweb
zh路西法39 分钟前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(一):从电梯出发的状态模式State Pattern
c++·决策树·状态模式
大G哥41 分钟前
java提高正则处理效率
java·开发语言
VBA63371 小时前
VBA技术资料MF243:利用第三方软件复制PDF数据到EXCEL
开发语言
轩辰~1 小时前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
小_太_阳1 小时前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
向宇it1 小时前
【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
开发语言·unity·c#·编辑器·游戏引擎
lxyzcm1 小时前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23