Linux文件属性2——使用stat函数获取文件属性
程序员文章站
2022-05-24 15:42:17
...
以下内容源于朱有鹏《物联网大讲堂》课程的学习整理,如有侵权,请告知删除。
一、获取文件属性
1、stat、fstat、lstat函数简介
- 每个文件都附带有一些属性;
- 属性信息存在于文件本身中,只能被专用的API打开看到;
- API有stat、fstat、lstat三个,作用一样,参数不同,细节略有不同。
(1)linux命令行下,用stat命令查看文件属性信息
- 如stat a.out;
- 用man 1 stat,man 2 stat查看,发现stat命令内部就是使用stat系统调用来实现的;
(2)stat的作用
- 内核将某个文件的属性信息结构体填充到stat函数的buf中;(参数里面,有指针,而且不加const,说明是输出型参数)
- 当stat这个API调用从内核返回时,buf这个结构体就被文件的属性信息填充好了;
- 通过查看buff结构体变量的元素,就可以得知该文件的各种属性。
(3)fstat和stat的区别
- stat是从文件名出发得到文件属性信息结构体,而fstat是从一个已经打开的文件fd出发,得到一个文件的属性信息;
- 如果文件没有打开就用stat,如果文件已经被打开用fstat效率会更高(stat是从磁盘去读取文件的,而fstat是从内存读取动态文件的);
(4)lstat和stat/fstat的差别
- 对于符号链接文件,stat和fstat查阅的是符号链接文件指向的文件的属性,而lstat查阅的是符号链接文件本身的属性。
2、struct stat结构体简介
- struct stat是内核定义的一个结构体,在<sys/stat.h>中声明,见上图;
- 这个结构体中的所有元素加起来就是文件属性信息;
3、代码实战
- 写代码查看一些常见属性信息,和直接用stat命令对比
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define NAME "1.txt" //这样写的时候,注意该程序的路径是在该文件的同路径下
int main(void)
{
int ret = -1;
struct stat buf;
//struct stat buf={0};初始化方法1,或者使用下面的
memset(&buf, 0, sizeof(buf)); // memset后buf中全是0
ret = stat(NAME, &buf); // stat后buf中有内容了
if (ret < 0)
{
perror("stat");
exit(-1);
}
// 成功获取了stat结构体,从中可以得到各种属性信息了
printf("inode = %d.\n", buf.st_ino);
printf("size = %d bytes.\n", buf.st_size);
printf("st_blksize = %d.\n", buf.st_blksize);
return 0;
}
二、stat函数的应用案例
1、用代码判断文件类型
(1)文件类型就是-、d、l……
(2)文件类型标志在struct stat结构体的mode_t st_mode元素中
- unsigned int类型,每个bit位表示一个含义;
- 由很多个标志位共同构成,记录了很多信息,如果要查找时按位&操作就知道结果了;
- 但是这些位定义不容易记住,因此linux系统事先定义很多宏来进行相应操作;
- 譬如S_ISREG宏返回值是1表示这个文件是一个普通文件,如果文件不是普通文件则返回值是0;
2、用代码判断文件权限设置
(1)st_mode中除了记录文件类型,还记录着一个重要信息:文件权限。
(2)linux并没有给文件权限测试提供宏操作,而是只提供位掩码,所以我们只能用位掩码来判断是否具有相应权限。
3、代码展示
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define NAME "1.txt"
int main(void)
{
int ret = -1;
struct stat buf;
memset(&buf, 0, sizeof(buf)); // memset后buf中全是0
ret = stat(NAME, &buf); // stat后buf中有内容了
if (ret < 0)
{
perror("stat");
exit(-1);
}
#if 0
// 判断这个文件属性
//int result = S_ISREG(buf.st_mode);
int result = S_ISDIR(buf.st_mode);
printf("result = %d\n", result);
#endif
// 文件权限测试
//unsigned int result = (buf.st_mode & S_IRWXU) >> 8;
unsigned int result = ((buf.st_mode & S_IRUSR)? 1: 0);
printf("file owner: %u.\n", result);
return 0;
}
下一篇: LOG4J2 配置详解