Linux学习:文件属性函数

1、stat 命令

stat filename ,功能上类似于 ls - l。

2、stat 函数

(1)头文件:

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

(2)原型:

 int stat(const char *pathname, struct stat *buf);

(3)参数:
1)pathname :文件名称(包含路径,不写默认当前目录下)。
2)buf : 结构体:结构体元素为文件信息。
(4)返回值:
成功返回 0; 失败返回 -1,设置 erron 。

3、使用 stat 函数获得文件大小

struct stat st;
int ret = stat(“bigtext.txt”, &st);
if(ret == -1){
perror(“stat error”);
exit(1);
}
printf(“file size = %d\n”, (int)st.st_size); // 注意类型强转,否则编译有警告

4、使用 stat 函数获得文件类型和权限

对应结构体中的元素是 mode_t 和st_mode。
类型:
(1)mode_t (本质是一个 16 位的整数,也称位图)。
(2)st_mode :16 位整数,分 5 块(特殊权限位不需要掌握),如下图所示:
在这里插入图片描述
(1)0-2 bit :其他人权限
1)宏:S_IROTH ;八进制数:0004 ;权限:读权限。
2)宏:S_IWOTH ;八进制数:0002 ;权限:写权限 。
3)宏:S_IXOTH ;八进制数:0001 ;权限:执行权限 。
(2) 3-5 bit :所属组权限
1)宏:S_IRGRP;八进制数: 0040 ;权限:读权限 。
2)宏:S_IWGRP ;八进制数:0020 ;权限:写权限。
3)宏: S_IXGRP ;八进制数:0010 ;权限:执行权限。
(3) 6-8 bit : 文件所有者权限
1)S_IRUSR ;0400 ;读权限。
2)S_IWUSR ;0200; 写权限。
3)S_IXUSR ;0100; 执行权限。
(4)12-15 bit :文件类型
1)S_IFSOCK ;140000 ;套接字 。
2)S_IFLNK ;120000; 符号连接(软链接)。
3)S_IFREG ;100000 ;普通文件。
4)S_IFBLK ;060000 ;块设备。
5)S_IFDIR ;040000; 目录。
6)S_IFCHR ;020000; 字符设备。
7)S_IFIFO ;010000 ;管道。
8)S_IFMT ;170000; 掩码。

5、stat 、 lstat 、fstat 的 区别

int stat(const char *pathname, struct stat *buf);
int lstat(const char *pathname, struct stat *buf); // 前两个函数形式基本一样
int fstat(int fd, struct stat *buf);

主要是在查看软链接文件时候有区别:
(1)stat 是 读取“软链接指向的文件”的属性 (穿透软链接)。
(2)lstat 是 读取“软链接本身文件”的属性(不穿透软链接)。
(3)fstat 是使用 open 打开文件后,通过文件描述符读取文件属性。

6、实现 ls -l filename

代码如下:

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
int main(int argc, char *argv[])
{
 if(argc < 2){ 
 perror("./a.out filename\n");
 return -1;
 }
 struct stat sb ;
if( lstat(argv[1], &sb ) < 0 ) // 函数调用失败,打印错误信息,否则不执行if,表示获得信息成功
{
 perror("stat err"); 
 return -1;
}
// 代码执行到这个位置,意味着获得信息成功
 char fileMode[11] = {0}; // 比如 drwxr-xr-x 字符串 共10位+ \0
memset( fileMode, '-', 10); // 最后一位不格式
 //先搞定文件类型
 if(S_ISREG(sb.st_mode)) fileMode[0] = '-'; // regular file
 if(S_ISDIR(sb.st_mode)) fileMode[0] = 'd'; // directory
 if(S_ISCHR(sb.st_mode)) fileMode[0] = 'c'; // character device
 if(S_ISBLK(sb.st_mode)) fileMode[0] = 'b'; // block device
 if(S_ISFIFO(sb.st_mode)) fileMode[0] = 'p'; // FIFO (named pipe)
 if(S_ISLNK(sb.st_mode)) fileMode[0] = 'l'; // symbolic link
 if(S_ISSOCK(sb.st_mode)) fileMode[0] = 's'; // socket
 //在搞定三类用户的权限
 //用户
 if(S_IRUSR & sb.st_mode) fileMode[1] = 'r'; // 否则因为memset ,默认是 ’-’
 if(S_IWUSR & sb.st_mode) fileMode[2] = 'w';
 if(S_IXUSR & sb.st_mode) fileMode[3] = 'x';
 //组用户
 if(S_IRGRP & sb.st_mode) fileMode[4 ]= 'r';
 if(S_IWGRP & sb.st_mode) fileMode[5] = 'w';
 if(S_IXGRP & sb.st_mode) fileMode[6] = 'x';
 //其他用户
 if(S_IROTH & sb.st_mode) fileMode[7] = 'r';
 if(S_IWOTH & sb.st_mode) fileMode[8] = 'w';
if(S_IXOTH & sb.st_mode) fileMode[9] = 'x';
 //获得用户名和组名
 char *User = getpwuid(sb.st_uid)->pw_name;
char *Group = getgrgid(sb.st_gid)->gr_name;
//获得时间
struct tm *fileTm = localtime(&sb.st_ctim.tv_sec);
 printf("%s %ld %s %s %ld %d月 %d %d:%d %s\n", fileMode, sb.st_nlink, User, Group, sb.st_size,
fileTm->tm_mon+1, fileTm->tm_mday, fileTm->tm_hour, fileTm->tm_min,
 argv[1]);
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值