欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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系统调用来实现的;

Linux文件属性2——使用stat函数获取文件属性


(2)stat的作用

  • 内核将某个文件的属性信息结构体填充到stat函数的buf中;(参数里面,有指针,而且不加const,说明是输出型参数
  • 当stat这个API调用从内核返回时,buf这个结构体就被文件的属性信息填充好了;
  • 通过查看buff结构体变量的元素,就可以得知该文件的各种属性。

Linux文件属性2——使用stat函数获取文件属性


Linux文件属性2——使用stat函数获取文件属性


(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;

Linux文件属性2——使用stat函数获取文件属性


2、用代码判断文件权限设置

(1)st_mode中除了记录文件类型,还记录着一个重要信息:文件权限。

(2)linux并没有给文件权限测试提供宏操作,而是只提供位掩码,所以我们只能用位掩码来判断是否具有相应权限。

Linux文件属性2——使用stat函数获取文件属性

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;
}