stat函数
一、stat 函数,获取文件元数据
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
二、stat结构体字段详情如下:
struct stat{
dev_t st_dev; //设备号,文件所在磁盘位置。高8位主,低8位次
ino_t st_ino; //inode num ls -i 可查看i节点号
mode_t st_mode;//文件的类型和存取的权限. (st_mode & S_IFMT)得到文件类型,(st_mode & 07777) 获取权限,并以8进制输出。
nlink_t st_nlink;//链向此文件的连接数(硬连接)
uid_t st_uid; //文件所属用户
gid_t st_gid; //文件所属组
dev_t st_rdev;//设备号,针对设备文件
off_t st_size;//文件大小,字节为单位
blksize_t st_blksize;//系统块的大小
blkcnt_t st_blocks;//文件所占块数
time_t st_atime;//最近存取时间(访问时间)
time_t st_mtime;//最近修改时间 ---实现ls中的时间
time_t st_ctime;//最近状态改变时间
}
/**********************
实现ls -l 功能
1、第一栏:文件的属性 2、第二栏:表示文件个数。如果是文件的话,那个数是1;如果是目录,那数目就是该目录中的文件个数。
3、第三栏:该文件或目录的拥有者。 4、第四栏:表示所属的组(group)。
5、 第五栏:表示文件大小。文件大小用byte来表示。 6、 第六栏:表示创建日期。以“月,日,时间”的格式表示。
7、第七栏:表示文件名
链接数 st_nlink
用户名 st_uid---再利用getpwuid得到用户struct passwd结构体。结构体pw_name为用户名
组名 st_gid ---利用getprgid(gid_t gid) 得到group字段的gr_name
文件大小 off_t st_size
时间 st_mtime
名称
如果是符号链接文件: 获取其指向的文件。 readlink. 符号链接文件用 lstat()来获取符号链接文件自身的状态。stat()查看符号链接所指向文件的状态
***********************/
1 #include<unistd.h> 2 #include<sys/types.h> 3 #include<sys/stat.h> 4 #include<fcntl.h> 5 #include<stdlib.h> 6 #include<stdio.h> 7 #include<errno.h> 8 #include<string.h> 9 #define ERR_EXIT(m)\ 10 do\ 11 {\ 12 perror(m);\ 13 exit(EXIT_FAILURE);\ 14 }while(0) //宏要求一条语句 15 #define MAJOR(x) (int)((unsigned short)x >> 8)//主设备号,高8位 16 #define MINOR(x) (int)((unsigned short)x & 0x00ff) //次设备号,低8位 17 int filetype(struct stat *buf);//打印文件类型 18 void filepermission(struct stat *buf,char *perm);//将权限bits位转换成字符形式 19 int main(int argc,char* argv[]) 20 { 21 if(argc!=2) 22 { 23 fprintf(stderr,"Usage %s file\n",argv[0]); 24 exit(EXIT_FAILURE); 25 } 26 struct stat sbuf; 27 //打印文件名 28 printf("Filename:%s\n",argv[1]); 29 if(stat(argv[1],&sbuf)==-1)//ls -li argv[1] df argv[1] 30 { 31 ERR_EXIT("stat error"); 32 } 33 //打印设备号和i结点号码。主设备号决定了系统用什么驱动程序访问设备 34 printf("FILE number:major %d,minor %d,inode %d \n",MAJOR(sbuf.st_dev),MINOR(sbuf.st_dev),(int)sbuf.st_ino); 35 36 if(filetype(&sbuf))//获取文件类型。 37 { 38 printf("Device number:major %d,minor %d\n",MAJOR(sbuf.st_rdev),MINOR(sbuf.st_rdev));//如果是设备文件,打印出主次设备号 39 } 40 //获取文件权限 41 char perm[]="----------";//第一位是类型 42 filepermission(&sbuf,perm); 43 //打印文件权限 44 printf("File Permission bits=%o %s\n",(sbuf.st_mode&07777),perm); 45 return 0; 46 }
//打印输出文件类型。 47 int filetype(struct stat *buf) 48 { 49 int flag=0; 50 printf("Filetype: "); 51 mode_t mode; 52 mode=buf->st_mode;//需要与掩码与得到的结果可判定文件类型 53 switch(mode & S_IFMT){ 54 case S_IFSOCK: 55 printf("socket \n"); 56 break; 57 case S_IFLNK: 58 printf("symbolic link\n"); 59 break; 60 case S_IFREG: 61 printf("regular file\n"); 62 break; 63 case S_IFBLK: 64 printf("block file\n"); 65 break; 66 case S_IFDIR: 67 printf("directory\n"); 68 break; 69 case S_IFCHR: 70 flag=1;//设备文件 71 printf("character device\n"); 72 break; 73 case S_IFIFO: 74 printf("FIFO\n"); 75 break; 76 default : 77 printf("unknown file type\n"); 78 break; 79 } 80 return flag; 81 }
//打印文件权限 82 void filepermission(struct stat *buf,char * perm) 83 { 84 85 perm[0]='?';//先获取类型 86 mode_t mode; 87 mode=buf->st_mode;//需要与掩码与得到的结果可判定文件类型 88 switch(mode & S_IFMT){ 89 case S_IFSOCK: 90 perm[0]='s'; 91 break; 92 case S_IFLNK: 93 perm[0]='l'; 94 break; 95 case S_IFREG: 96 perm[0]='-'; 97 break; 98 case S_IFBLK: 99 perm[0]='b'; 100 break; 101 case S_IFDIR: 102 perm[0]='d'; 103 break; 104 case S_IFCHR: 105 perm[0]='c'; 106 break; 107 case S_IFIFO: 108 perm[0]='p'; 109 break; 110 } 111 //再获取权限.也可利用算法实现664 ----rw rw w 112 if(mode & S_IRUSR) 113 perm[1]='r'; 114 if(mode & S_IWUSR) 115 perm[2]='w'; 116 if(mode & S_IXUSR) 117 perm[3]='x'; 118 if(mode & S_IRGRP) 119 perm[4]='r'; 120 if(mode & S_IWGRP) 121 perm[5]='w'; 122 if(mode & S_IXGRP) 123 perm[6]='x'; 124 if(mode & S_IROTH) 125 perm[7]='r'; 126 if(mode & S_IWOTH) 127 perm[8]='w'; 128 if(mode & S_IXOTH) 129 perm[9]='x'; 130 perm[10]='\0'; 131 }