stat结构体以及文件状态相关函数

来源:互联网 发布:雷蛇金丝魔蛛 知乎 编辑:程序博客网 时间:2024/05/22 17:14

基本的stat结构体的大体组成成员如下:

    struct stat

    {

        mode_t st_mode;  //文件类型或文件模式

        ino_t st_ino;   //目录进入点的inode节点

        dev_t st_dev;   //系统文件设备

        dev_t st_rdev;  //特殊文件设备

        nlink_t st_nlink;   //连接该文件的硬件连接数,刚创建的文件默认为1

        uid_t st_uid;   //用户id

        gid_t st_gid;  //用户所在组id

        off_t st_size;  //文件的大小

        time_t st_atime;  //文件最后访问时间

        time_t st_mtime;  //最近修改时间

        time_t st_ctime;  //i节点状态最后改变时间

        blksize_t st_blksize;

        blkcnt_t st_blocks;

    };

上面结构体包含了文件状态信息。下面看三个获取文件状态信息的函数:

    #include <sys/stat.h>

    int stat(const char *restrict pathname,struct stat *restrict buf);

    int fstat(int fileds,struct stat *buf); 

    int lstat(const char *restrict pathname,struct stat *restrict buf); 

函数成功返回0,失败返回-1;

三者定义上可义看出,fstat是获取已在文件描述符fileds上打开的文件信息。

而lstat可以获取一个符号链接的相关信息,而stat不能。

stat相关函数以及stat结构体在ls -l命令中起了很重要的作用。

    

文件类型:

linux下包含了很多的文件类型:普通文件、目录文件、块特殊文件、字符特殊文件、FIFO文件、套接字、符号链接。文件类型包含在stat结构体的st_mode成员中。可以用下面的宏确定文件类型,这些宏的参数都是stat结构体中的st_mode成员。

sys/stat.h文件中的宏定义:

#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG )

#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR )

#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK )

#define S_ISCHR (mode) (((mode) & S_IFMT) == S_IFCHR)

#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO)

#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK )

#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)

    S_ISREG:普通文件

    S_ISDIR:目录文件 

    S_ISBLK:块设备文件 

    S_ISCHR:字符特殊文件 

    S_ISFIFO:管道或FIFO文件 

    S_ISLNK:符号链接 

    S_ISSOCK:套接字文件 

下面应用这些宏判断输入的文件的文件类型:

    int judge_file(const char *pathname)

    {

        struct stat buf;

        char *ptr = NULL;

        if (stat(pathname,&buf) < 0)

        {

            printf("stat failer!\n");

            return -1;

        }    

        if (S_ISREG(buf.st_mode))

            ptr = "普通文件";

        else if (S_ISDIR(buf.st_mode))

            ptr = "目录文件";

        else if (S_ISCHR(buf.st_mode))

            ptr = "字符特殊文件";

        else if (S_ISBLK(buf.st_mode))

            ptr = "块设备问文件";

        else if (S_ISFIFO(buf.st_mode))

            ptr = "管道或FIFO文件";

        else if (S_ISLNK(buf.st_mode))

            ptr = "符号链接";

        else if (S_ISSOCK(buf.st_mode))

            ptr = "套接字"

        else

            ptr = "error!";

        printf("%s\n",ptr);

        return 0;

    }

 

设置用户ID和组ID

    实际用户ID、实际组ID标识我们究竟是谁;

    有效用户ID、有效组ID以及附加组ID决定了文件的访问权限。

    每个文件都有一个所有者,所有者由stat结构中的st_uid表示,组所有者则由st_gid表示。可以用常理S_ISUID和S_ISGID测试。

 

文件访问权限:

    每个文件都有9个访问权限位,分为三类,u表示用户,g表示组,o表示其他。

    摘自sys/stat.h

    st_mode屏蔽     意义         屏蔽位

    S_IRUSR        用户读         0400

    S_IWUSR        用户写         0200

    S_IXUSR        用户执行       0100

 

    S_IRDRP        组读           0040

    S_IWGRP        组写           0020

    S_IXGRP        组执行         0010

 

    S_IROTH        其他读         0004

    S_IWOTH        其他写         0002

    S_IXOTH        其他执行       0001

下面看一个具体的获取文件权限的函数

    int get_file_mode(int mode,char *str)

    {       

        strcpy(str, "----------");           /* default=无参数 */

         /*获取文件类型*/

        if (S_ISDIR(mode))  

        str[0] = 'd';    /* 目录      */

        if (S_ISCHR(mode)) 

        str[0] = 'c';    /* 字符设备   */

        if (S_ISBLK(mode))  

        str[0] = 'b';    /* 块设备     */

        /* 用户权限  */ 

        if (mode & S_IRUSR) 

        str[1] = 'r';   

        if (mode & S_IWUSR) 

        str[2] = 'w';

        if (mode & S_IXUSR) 

        str[3] = 'x';

        /* 组权限 */ 

        if (mode & S_IRGRP) 

        str[4] = 'r';    

        if (mode & S_IWGRP) 

        str[5] = 'w';

        if (mode & S_IXGRP)

        str[6] = 'x';

         /* 其人的权限 */ 

        if (mode & S_IROTH) 

        str[7] = 'r';    

        if (mode & S_IWOTH) 

        str[8] = 'w';

        if (mode & S_IXOTH) 

        str[9] = 'x';

    }

 

chmod和fchmod函数:更改现有文件的权限:

    #include <sys/stat.h>

    int chmod(const char *pathname,mode_t mode);

    int fchmod(int fileds,mode_t mode);

    函数中的mode参数为上面所说的9个类型再加上S_IRWXU、S_IRWXG、S_IRWXO.

    S_IRWXU = S_IRUSR | S_IWUSR | S_IXUDR

    S_IRWXG = S_IRGRP | S_IWGRP | S_IXGRP

    S_IRWXO = S_IROTH | S_IWOTH | S_I

 

读目录:

    #include <dirent.h>

    DIR *opendir(const char *pathname);成功返回指针

    struct dirent *readdir(DIR *dp); 

    int closedir(DIR *dp)

    dirent结构体的定义如下:

    struct dirent

    {

        ino_t d_ino;

        char d_name[NAME_MAX+1];

    }

原创粉丝点击