Linux 文件操作(三) —— 获取并打印某个文件的属性(文件类型、执行权限、文件大小)

本文介绍了Linux系统中用于获取文件属性的stat、lstat和fstat函数,详细阐述了它们的参数、返回值及实际应用。通过示例代码展示了如何获取文件类型、权限、大小和访问时间,帮助读者理解这些函数的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        目录

1、获取文件属性 stat / lstat / fstat

(1) 参数 path

(2) 参数 buf

(3) 返回值

2、获取并打印某个文件的属性

(1) 获取文件类型

(2) 获取文件权限

(3) 获取文件大小

(4) 获取上一次的访问时间

(5) 最终代码


1、获取文件属性 stat / lstat / fstat

stat / lstat / fstat 函数的作用是获取文件属性,stat 函数可以通过文件路径获取到任意文件(链接文件除外)的属性,lstat 获取的是链接文件的属性,fstat 是通过文件描述符获取到文件属性。

 下面以 stat 函数为例介绍参数和返回值

(1) 参数 path

输入型参数,代表文件所在路径。如果path对应的文件是一个符号链接,那么stat 获取到的是目标文件的属性,而不是链接文件的属性;如果要获取链接文件的属性,需使用 lstat。

(2) 参数 buf

输出型参数,获取到的文件属性会放入这个结构体中。结构体的大致定义如下:

(3) 返回值

成功返回 0,失败返回 -1

2、获取并打印某个文件的属性

假设我们有一个 log.txt文件,我们要获取这个文件的类型、访问权限、文件大小、上一次访问时间,最终完整代码访问最后,中间是一些零碎的代码。

(1) 获取文件类型

Linux提供了一些宏函数来判断是哪种文件类型

  • S_ISREG(st_mode)  :是否为常规文件?
  • S_ISDIR(st_mode)  :是否为目录?
  • S_ISCHR(st_mode)  :是否为字符设备?
  • S_ISBLK(st_mode)  :是否为块设备?
  • S_ISFIFO(st_mode) :是否为FIFO文件?
  • S_ISLNK(st_mode)  :是否为链接文件?
  • S_ISSOCK(st_mode) :是否为Socket文件?
# st 代表获取到的文件属性结构体
if(S_ISREG(st.st_mode))
    printf("-");
else if(S_ISREG(st.st_mode))
    printf("d");
else if(S_ISCHR(st.st_mode))
    printf("c");
else if(S_ISBLK(st.st_mode))
    printf("b");
else if(S_ISFIFO(st.st_mode))
    printf("p");
else if(S_ISLNK(st.st_mode))
    printf("l");
else         
    printf("s");        // 其他归为套接字文件类型

(2) 获取文件权限

其实Linux也提供了一些宏来判断该文件是否具备指定权限,但是我们要遍历该文件的所有权限,st_mode成员存储权限的方式是位图存储,每个权限对应 1bit ,我们可以通过移位来获取这九个权限。

int i = 8;
for(; i >= 0; i--)     
{
    if((st.st_mode >> i) & 1)    // 先判断有无权限
    {
        // 判断具体是哪一种权限
        if(i % 3 == 0)
        {
            printf("r");        // 读权限
        }
        else if(i % 3 == 1) 
        {
            printf("w");        // 写权限
        }
        else
        {
            printf("x);        // 执行权限
        }
    }
    else
    {
        printf("-");        // 无权限
    }
}

(3) 获取文件大小

printf(" %d", (int)st.st_size);

(4) 获取上一次的访问时间

获取时间需要使用 localtime 函数转换成我们可以识别的格式,localtime函数的声明如下:

 我们重点看返回的结构体定义,这里包含了我们需要的时间信息

struct tm t;
t = localtime(st.st_atime);
// 月是从0开始计的,所以要加 1
printf(" %d-%d-%d %d:%d",t.tm_year, t.tm_month+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);

(5) 最终代码

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

int main(){
	struct stat st;
	int ret = stat("./log.txt",&st);
	if(ret < 0)
	{
		perror("stat");
		return -1;
	}

	if(S_ISREG(st.st_mode))
		    printf("-");
	else if(S_ISREG(st.st_mode))
		    printf("d");
	else if(S_ISCHR(st.st_mode))
		    printf("c");
	else if(S_ISBLK(st.st_mode))
		    printf("b");
	else if(S_ISFIFO(st.st_mode))
		    printf("p");
	else if(S_ISLNK(st.st_mode))
		    printf("l");
	else         
		    printf("s");        
				
	int i = 8;
	for(;i >= 0; i--)
	{
		if((st.st_mode >> i) & 1)
		{
			if(i%3 == 2)
				printf("r");
			else if(i%3 == 1)
				printf("w");
			else
				printf("x");
		}
		else
			printf("-");
	}

	printf(" %d", (int)st.st_size);

	struct tm* t;
	t = localtime(&(st.st_atime));
	// 月是从0开始计的,所以要加 1
	printf(" %d-%d-%d %d:%d\n",t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min);
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值