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