获取文件属性——stat()函数(七)

目录

  一 stat函数

二 .示例代码 :struct stat 结构体

三 st_mode 变量

3.1测试:判断该文件对其它用户是否具有读权限

四 利用宏判断文件类型

五 fstat 和 lstat 函数

1.fstat 函数

2.lstat 函数

五 案列:代码测试 


  一 stat函数

函数原型:

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

函数参数及返回值含义如下:

  • pathname:用于指定一个需要查看属性的文件路径。
  • buf:struct stat 类型指针,用于指向一个 struct stat 结构体变量。调用 stat 函数的时候需要传入一个 struct stat 变量的指针,获取到的文件属性信息就记录在 struct stat 结构体中。
  • 返回值:成功返回 0;失败返回-1,并设置 error。

struct stat 是内核定义的一个结构体,在头文件中申明,所以可以在应用层使用,这个结构体 中的所有元素加起来构成了文件的属性信息,结构体内容如下所示:

二 .示例代码 :struct stat 结构体

struct stat 
{ 
 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; /* 设备号(指针对设备文件) */ 
 off_t st_size; /* 文件大小(以字节为单位) */ 
 blksize_t st_blksize; /* 文件内容存储的块大小 */ 
 blkcnt_t st_blocks; /* 文件内容所占块数 */ 
 struct timespec st_atim; /* 文件最后被访问的时间 */ 
 struct timespec st_mtim; /* 文件内容最后被修改的时间 */ 
 struct timespec st_ctim; /* 文件状态最后被改变的时间 */
};
  1. st_dev:该字段用于描述此文件所在的设备。不常用,可以不用理会。
  2. st_ino:文件的 inode 编号。 st_mode:该字段用于描述文件的模式,譬如文件类型、文件权限都记录在该变量中
  3. st_nlink:该字段用于记录文件的硬链接数,也就是为该文件创建了多少个硬链接文件。链接文件可以 分为软链接(符号链接)文件和硬链接文件,关于这些内容后面再给大家介绍。
  4. st_uid、st_gid:此两个字段分别用于描述文件所有者的用户 ID 以及文件所有者的组 ID,后面再给大家 介绍。
  5. st_rdev:该字段记录了设备号,设备号只针对于设备文件,包括字符设备文件和块设备文件,不用理会。
  6. st_size:该字段记录了文件的大小(逻辑大小),以字节为单位。
  7. st_atim、st_mtim、st_ctim:此三个字段分别用于记录文件最后被访问的时间、文件内容最后被修改的时 间以及文件状态最后被改变的时间,都是 struct timespec 类型变量

代码示例: 

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{

    struct stat mystat;
    int ret = stat("./test.txt",&mystat);
    if(-1 == ret)
    {
        perror("stat error ");
        exit(-1);
    }
    printf("inode 编号:%ld ,mode :%d  size:%ld\n",mystat.st_ino,mystat.st_mode,mystat.st_size);
    printf("gid 编号:%d ,uid :%d  size:%ld\n",mystat.st_gid,mystat.st_uid,mystat.st_size);


}

三 st_mode 变量

st_mode 是 struct stat 结构体中的一个成员变量,是一个 32 位无符号整形数据,该变量记录了文件的类 型、文件的权限这些信息,其表示方法如下所示:

                                         图3.1st_mode 数据信息示意图

在以前学的 open 函数的第三 个参数 mode 时也用到了类似的图,唯一不同的在于 open 函数的 mode 参数只涉及到 S、U、G、O 这 12 个 bit 位,并不包括用于描述文件类型的 4 个 bit 位。

  • O 对应的 3 个 bit 位用于描述其它用户的权限;
  • G 对应的 3 个 bit 位用于描述同组用户的权限;
  • U 对应的 3 个 bit 位用于描述文件所有者的权限;
  • S 对应的 3 个 bit 位用于描述文件的特殊权限。

这些 bit 位表达内容与 open 函数的 mode 参数相对应。同样,在 mode 参数中表示权限 的宏定义,在这里也是可以使用的,这些宏定义如下(以下数字使用的是八进制方式表示):

S_IRWXU 00700 owner has read, write, and execute permission 
S_IRUSR 00400 owner has read permission 
S_IWUSR 00200 owner has write permission 
S_IXUSR 00100 owner has execute permission 
S_IRWXG 00070 group has read, write, and execute permission 
S_IRGRP 00040 group has read permission 
S_IWGRP 00020 group has write permission 
S_IXGRP 00010 group has execute permission 
S_IRWXO 00007 others (not in group) have read, write, and execute permission 
S_IROTH 00004 others have read permission 
S_IWOTH 00002 others have write permission 
S_IXOTH 00001 others have execute permission 

 这些宏很好理解,R就是read,W就是write,X就是execute,SR就是文件所属者,GRP同组,OTH就是其他组

3.1测试:判断该文件对其它用户是否具有读权限

譬如, 判断该文件对其它用户是否具有读权限,可以通过以下方法测试(假设 st 是 struct stat 类 型变量):

struct stat file_stat; 


/* 判断该文件对其它用户是否具有读权限 */ 
 if (file_stat.st_mode & S_IROTH) 
 printf("Read: Yes\n"); 
 else 
 printf("Read: No\n");

四 利用宏判断文件类型

“文件类型”这 4 个 bit 位

这 4 个 bit 位用于描述该文件的类型,譬如该文件是 普通文件、还是链接文件、亦或者是一个目录等,那么就可以通过这 4 个 bit 位数据判断出来,如下所示:

S_IFSOCK 0140000 socket(套接字文件) 
S_IFLNK 0120000 symbolic link(链接文件) 
S_IFREG 0100000 regular file(普通文件) 
S_IFBLK 0060000 block device(块设备文件) 
S_IFDIR 0040000 directory(目录) 
S_IFCHR 0020000 character device(字符设备文件) 
S_IFIFO 0010000 FIFO(管道文件)

可以使用 Linux 系统封装好的宏来进行判断属于什么文件,如下所示(m 是 st_mode 变 量):  

S_ISREG(m) #判断是不是普通文件,如果是返回 true,否则返回 false 
S_ISDIR(m) #判断是不是目录,如果是返回 true,否则返回 false 
S_ISCHR(m) #判断是不是字符设备文件,如果是返回 true,否则返回 false 
S_ISBLK(m) #判断是不是块设备文件,如果是返回 true,否则返回 false 
S_ISFIFO(m) #判断是不是管道文件,如果是返回 true,否则返回 false 
S_ISLNK(m) #判断是不是链接文件,如果是返回 true,否则返回 false 
S_ISSOCK(m) #判断是不是套接字文件,如果是返回 true,否则返回 false 

/* 判断是不是普通文件 */ 
if (S_ISREG(st.st_mode)) { 
 /* 是 */ 
} 
 
/* 判断是不是目录 */ 
if (S_ISDIR(st.st_mode)) { 
 /* 是 */ 
} 

switch (file_stat.st_mode & S_IFMT) { 
 case S_IFSOCK: printf("socket"); break; 
 case S_IFLNK: printf("symbolic link"); break; 
 case S_IFREG: printf("regular file"); break; 
 case S_IFBLK: printf("block device"); break; 
 case S_IFDIR: printf("directory"); break; 
 case S_IFCHR: printf("character device"); break; 
 case S_IFIFO: printf("FIFO"); break; 
 } 

上面代码示例的方法都可用

五 fstat 和 lstat 函数

除了 stat 函数之外,还可以使用 fstat 和 lstat 两个系统调用来获 取文件属性信息。fstat、lstat 与 stat 的作用一样,但是参数、细节方面有些许不同。

1.fstat 函数

fstat 与 stat 区别在于,stat 是从文件名出发得到文件属性信息,不需要先打开文件;而 fstat 函数则是从 文件描述符出发得到文件属性信息,所以使用 fstat 函数之前需要先打开文件得到文件描述符。具体该用 stat还是 fstat,看具体的情况;譬如,并不想通过打开文件来得到文件属性信息,那么就使用 stat,如果文件已 经打开了,那么就使用 fstat。 fstat 函数原型如下(可通过"man 2 fstat"命令查看):

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
 
int fstat(int fd, struct stat *buf);
  1. 第一个参数 fd 表示文件描述符,
  2. buf:struct stat 类型指针,用于指向一个 struct stat 结构体变量。调用 stat 函数的时候需要传入一个 struct stat 变量的指针,获取到的文件属性信息就记录在 struct stat 结构体中。
  3. 返回值:成功返回 0;失败返回-1,并设置 error。

2.lstat 函数

lstat()与 stat、fstat 的区别在于,对于符号链接文件,stat、fstat 查阅的是符号链接文件所指向的文件对 应的文件属性信息,而 lstat 查阅的是符号链接文件本身的属性信息。 lstat 函数原型如下所示:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
 
int lstat(const char *pathname, struct stat *buf); 
  • pathname:用于指定一个需要查看属性的文件路径。
  • buf:struct stat 类型指针,用于指向一个 struct stat 结构体变量。调用 stat 函数的时候需要传入一个 struct stat 变量的指针,获取到的文件属性信息就记录在 struct stat 结构体中。
  • 返回值:成功返回 0;失败返回-1,并设置 error。

五 案列:代码测试 

(1)获取文件的 inode 节点编号以及文件大小,并将它们打印出来。

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

int main(void) 

{ 
 struct stat file_stat; 
 int ret; 
 
 /* 获取文件属性 */ 
 ret = stat("./test_file", &file_stat); 
 if (-1 == ret) { 
 perror("stat error"); 
 exit(-1); 
 } 
 
 /* 打印文件大小和 inode 编号 */ 
 printf("file size: %ld bytes\n" 
 "inode number: %ld\n", file_stat.st_size, 
 file_stat.st_ino); 
 exit(0); 

} 

(2)获取文件的类型,判断此文件对于其它用户(Other)是否具有可读可写权限。

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

int main(void) 

{ 
 struct stat file_stat; 
 int ret; 
 
 /* 获取文件属性 */ 
 ret = stat("./test_file", &file_stat); 
 if (-1 == ret) { 
 perror("stat error"); 
 exit(-1); 
 } 
 
 /* 判读文件类型 */ 
 switch (file_stat.st_mode & S_IFMT) { 
 case S_IFSOCK: printf("socket"); break; 
 case S_IFLNK: printf("symbolic link"); break; 
 case S_IFREG: printf("regular file"); break; 
 case S_IFBLK: printf("block device"); break; 
 case S_IFDIR: printf("directory"); break; 
 case S_IFCHR: printf("character device"); break; 
 case S_IFIFO: printf("FIFO"); break; 
 } 
 
 printf("\n"); 
 
 /* 判断该文件对其它用户是否具有读权限 */ 
 if (file_stat.st_mode & S_IROTH) 
 printf("Read: Yes\n"); 
 else 
 printf("Read: No\n"); 
 
 /* 判断该文件对其它用户是否具有写权限 */ 
 if (file_stat.st_mode & S_IWOTH) 
 printf("Write: Yes\n"); 
 else 
 printf("Write: No\n"); 
 
 exit(0); 

} 

  • 9
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@ChenPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值