目录
1 获取文件属性
1)stat
2)提取文件的权限
3)提取文件的类型
4)提取文件所属用户名【getpwuid函数】
5)提取文件所属组用户名【getgrgid函数】
6)完整代码:
1 获取文件属性
1)stat
功能:获取文件的属性;
原型:
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int stat(const char *pathname, struct stat *statbuf);
参数:
char *pathname:指定要获取属性的文件路径以及名字;
struct stat *statbuf:存储获取到的属性;
返回值:
成功,返回0;
失败,返回-1,更新errno;
结构体成员:
vi -t stat 或者 man手册往下翻
struct stat {
ino_t st_ino; /* Inode number */ inode号
mode_t st_mode; /* File type and mode */ 文件类型和权限
nlink_t st_nlink; /* Number of hard links */ 硬链接数
uid_t st_uid; /* User ID of owner */ 用户的uid
gid_t st_gid; /* Group ID of owner */ 组用户的gid
off_t st_size; /* Total size, in bytes */ 文件大小
struct timespec st_atim; /* Time of last access */ 最后一次被访问的时间
struct timespec st_mtim; /* Time of last modification */ 最后一次被修改的时间
struct timespec st_ctim; /* Time of last status change */ 最后一次改变状态的时间
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
2)提取文件的权限
mode_t st_mode 本质上是一个unsigned int类型,里面存储了文件的类型和权限。
st_mode中其中低9bits存储了文件的权限:[0bit - 8bit]
mode: 0100664 ---> rw-rw-r-- 664----> 110 110 100 ---> 0664 100 000 000 ---> 0400 ------------ 100 000 000 ===> 0400结果不等于0,需要打印'r'。否则打印'-' 664----> 110 110 100 ---> 0664 010 000 000 ---> 0200 ------------ 010 000 000 ===> 0200结果不等于0,需要打印'w'。否则打印'-' 664----> 110 110 100 ---> 0664 001 000 000 ---> 0100 ------------ 000 000 000 ===> 0000结果等于0,需要打印'-'。否则打印'x'
方法一:
void get_filePermission(mode_t m)
{
if(m & 0400)
putchar('r');
else
putchar('-');
if(m & 0200)
putchar('w');
else
putchar('-');
if(m & 0100)
putchar('x');
else
putchar('-');
///
if(m & 0040)
putchar('r');
else
putchar('-');
if(m & 0020)
putchar('w');
else
putchar('-');
if(m & 0010)
putchar('x');
else
putchar('-');
/
if(m & 0004)
putchar('r');
else
putchar('-');
if(m & 0002)
putchar('w');
else
putchar('-');
if(m & 0001)
putchar('x');
else
putchar('-');
}
方法二(2种循环):
void get_filePermission(mode_t m) //mode_t m = buf.st_mode
{
char buf[] = "rwx";
for(int i=0; i<9; i++)
{
if( (m & (0400>>i)) == 0)
{
putchar('-');
continue;
}
printf("%c", buf[i%3]);
//能运行到当前位置,则代表对应位置有权限
//需要判断是r w x中的哪一个
/*
switch(i%3)
{
case 0:
putchar('r');
break;
case 1:
putchar('w');
break;
case 2:
putchar('x');
break;
}
*/
}
return;
}
3)提取文件的类型
mode_t st_mode 本质上是一个unsigned int类型,里面存储了文件的类型和权限。
方法一:
man 2 stat --> st_mode --->see inode(7)
man 7 inode -->
S_ISREG(m) is it a regular file? -
S_ISDIR(m) directory? d
S_ISCHR(m) character device? c
S_ISBLK(m) block device? b
S_ISFIFO(m) FIFO (named pipe)? p
S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.) l
S_ISSOCK(m) socket? (Not in POSIX.1-1996.) s
若是该类型文件,则返回真,否则返回假
代码:
void get_fileType(mode_t m)
{
if(S_ISREG(m))
putchar('-');
else if(S_ISDIR(m))
putchar('d');
else if(S_ISCHR(m))
putchar('c');
return ;
}
方法二:
mode 0040775
S_IFMT 0170000 bit mask for the file type bit field
mode 0040775 ---> 000 100 000 111 111 101
S_IFMT 0170000 ---> 001 111 000 000 000 000 &
------------------------------
000 100 000 000 000 000 ---> 040000
与下列宏进行比较,与哪个相同,就是对应类型文件
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
mode: 0100664 ---> 001 000 000 110 110 100
S_IFMT 0170000 ---> 001 111 000 000 000 000 &
------------------------------
001 000 000 000 000 000 ---> 0100000
代码:
void get_fileType(mode_t m) //mode_t m = buf.st_mode
{
switch(m & S_IFMT)
{
case S_IFSOCK: putchar('s'); break;
case S_IFLNK: putchar('l'); break;
case S_IFREG: putchar('-'); break;
case S_IFDIR: putchar('d'); break;
}
return;
}
4)提取文件所属用户名【getpwuid函数】
uid_t st_uid; /* User ID of owner */ 用户的uid
getpwuid函数
功能:通过uid号获取用户的信息;
原型:
#include <sys/types.h> #include <pwd.h> struct passwd *getpwuid(uid_t uid);
参数:
uid_t uid:指定uid号;
返回值:
成功,返回结构体指针;
失败,返回NULL;更新errno;
结构体成员:
struct passwd {
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
代码:
struct passwd* pwd = getpwuid(buf.st_uid);
if(NULL == pwd)
{
ERR_MSG("getpwuid");
return -1;
}
printf("%s\n", pwd->pw_name);
5)提取文件所属组用户名【getgrgid函数】
gid_t st_gid; /* Group ID of owner */ 组用户的gid
功能:通过gid号获取组用户的信息;
原型:
#include <sys/types.h> #include <grp.h> struct group *getgrgid(gid_t gid);
参数:
gid_t gid:指定gid号;
返回值:
成功,返回结构体指针;
失败,返回NULL;更新errno;
结构体成员:
struct group {
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* NULL-terminated array of pointers
to names of group members */
};
代码:
struct group* grp = getgrgid(buf.st_gid);
if(NULL == grp)
{
ERR_MSG("getgrgid");
return -1;
}
printf("%s\n", grp->gr_name);
6)完整代码:
利用stat函数,打印类似ls -l的文件属性信息
方法一:
#include <stdio.h>
#include <head.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
int main(int argc, const char *argv[])
{
struct stat buf;
if(stat("./01_fileno.c",&buf) < 0 )
{
ERR_MSG("stat");
return -1;
}
//文件的硬链接数
printf("link:%ld\n", buf.st_nlink);
//文件的所属用户
printf("uid:%d\n", buf.st_uid);
//文件所属组用户
printf("gid:%d\n", buf.st_gid);
//文件大小
printf("size:%ld\n", buf.st_size);
//文件的修改时间
printf("time:%ld\n", buf.st_ctime);
//struct tm* info=NULL;
//info=localtime(&buf.st_mtime);
//printf("%d-%02d-%0d %02d:%02d:%02d\n", info->tm_year+1900, info->tm_mon+1, info->tm_mday, info->tm_hour, info->tm_min, info->tm_sec);
//文件的名字
return 0;
}
方法二:
#include <stdio.h>
#include <head.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
void get_filePermission(mode_t m)
{
char buf[]="rwx";
for(int i=0;i<9;i++)
{
if( (m & (0400)>>i) == 0)
{
putchar('-');
continue;
}
printf("%c",buf[i%3]);
}
putchar(' ');
}
void get_fileType(mode_t m)
{
/*
if(S_ISREG(m))
putchar('-');
else if(S_ISDIR(m))
putchar('d');
else if(S_ISCHR(m))
putchar('c');
else if(S_ISBLK(m))
putchar('b');
else if(S_ISFIFO(m))
putchar('p');
else if(S_ISLNK(m))
putchar('l');
else if(S_ISSOCK(m))
putchar('s');
*/
switch(m & S_IFMT)
{
case S_IFSOCK: putchar('s'); break;
case S_IFLNK: putchar('l'); break;
case S_IFREG: putchar('-'); break;
case S_IFDIR: putchar('d'); break;
}
return;
}
int main(int argc, const char *argv[])
{
struct stat buf;
if(stat("./01_fileno.c",&buf) < 0 )
{
ERR_MSG("stat");
return -1;
}
//文件的类型和权限
get_fileType(buf.st_mode);
get_filePermission(buf.st_mode);
//时间
struct tm* info=NULL;
info=localtime(&buf.st_mtime);
//文件的所属用户
struct passwd* pwd=getpwuid(buf.st_uid);
if(NULL == pwd)
{
ERR_MSG("getpwuid");
return -1;
}
//文件所属组用户
struct group* grp=getgrgid(buf.st_gid);
if(NULL == grp)
{
ERR_MSG("getgrgid");
return -1;
}
printf("%ld %s %s %ld %d月 %d %02d:%02d\n", buf.st_nlink, pwd->pw_name, grp->gr_name, buf.st_size, info->tm_mon+1, info->tm_mday, info->tm_hour, info->tm_min);
//文件的名字
return 0;
}