0801|IO进程线程day4【stat获取文件属性】

目录

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值