IO中文件属性函数以及目录相关函数

获取文件属性

stat

  • 功能:获取文件的属性

  • 原型:int stat(const char *pathname, struct stat *statbuf)

  • 参数:char *pathname:指定要获取属性的文件路径以及名字
    struct stat *statbuf:存储获取到的属性

  • 返回值:成功,返回0;失败,返回-1,更新errno

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

提取文件的权限

  • mode_t st_mode本质上是一个unsigned int类型,里面存储了文件的类型和权限
    st_mode中其中低9bits存储了文件的权限:【0bit —— 8bit】
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;
        }

        //能运行到当前位置,则代表对应位置有权限
        //需要判断是r w x中的哪一个
        /*
        switch(i%3)
        {
        case 0:
            putchar('r');
            break;
        case 1:
            putchar('w');                                   
            break;
        case 2:
            putchar('x');
            break;
        }
        */

        printf("%c", buf[i%3]);

    }
    return;
}

提取文件的类型

  • mode_t st_mode本质上是一个unsigned int类型,里面存储了文件的类型和权限
           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
           //方法二:
           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

提取文件所属用户名

  • uid_t st_uid 用户的id

getpwuid

  • 功能:通过uid号获取用户的信息
  • 原型: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);

提取文件所属组用户名

  • gid_t st_gid组用户的gid

getgrgid

  • 功能:通过gid号获取组用户的信息
  • 原型: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);

目录相关的函数

opendir

  • 功能:打开一个目录文件
  • 原型:DIR *opendir(const char *name)
  • 参数:char *name:指定要打开的目录的路径以及名字
  • 返回值:成功,返回指针;失败,返回NULL,更新errno;

closedir

  • 功能:关闭目录
  • 原型:int closedir(DIR *dirp)
  • 返回值:成功,返回0;失败,返回-1,更新errno;

readdir

  • 功能:读取目录
  • 原型:struct dirent *readdir(DIR *dirp)
  • 返回值:成功,返回结构体指针;失败,返回NULL;更新errno;目录读取完毕,返回NULL,不更新errno
         struct dirent {
               ino_t          d_ino;       /* Inode number */
               off_t          d_off;       /* Not an offset; see below */
               unsigned short d_reclen;    /* Length of this record */
               unsigned char  d_type;      /* Type of file; not supported
                                              by all filesystem types */
               char           d_name[256]; /* Null-terminated filename */
           };

练习:

从终端获取一个文件的路径以及名字。
若该文件是目录文件,则将该文件下的所有文件的属性显示到终端,类似ls -l该文件夹
若该文件不是目录文件,则显示该文件的属性到终端上,类似ls -l这单个文件

#include 
#include 
#include 
#include 
#include 
#include 
#include 
void get_filePermission(mode_t m)
{
	for(int i=0;i<9;i++)
	{
		if((m & 0400>>i) == 0)
		{
			putchar('-');
			continue;
		}
		switch(i%3)
		{
		case 0:putchar('r');break;
		case 1:putchar('w');break;
		case 2:putchar('x');break;
		}
	}
	return;
}
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');
}
int get_file(char *pathname)
{
		struct stat buf;
		if(stat(pathname,&buf) < 0)
		{
			ERRO_MES("stat");
			return -1;
		}
		//文件类型
		get_fileType(buf.st_mode);
		//文件权限
		get_filePermission(buf.st_mode);
		//文件硬链接数
		printf(" %ld",buf.st_nlink);
		//文件的所属用户
		struct passwd *pwd=getpwuid(buf.st_uid);
		if(NULL == pwd)
		{
			ERRO_MES("getpwuid");
			return -1;
		}
		printf(" %s",pwd->pw_name);
		//文件所属组用户
		struct group *grp=getgrgid(buf.st_gid);;
		if(NULL == grp)
		{
			ERRO_MES("getgrgid");
			return -1;
		}
		printf(" %s",grp->gr_name);
		//文件大小
		printf(" %ld",buf.st_size);
		//文件的修改时间
		struct tm *info = NULL;
		info=localtime(&buf.st_ctime);
		printf(" %d月 %d %02d:%02d",info->tm_mon+1,\
				info->tm_mday,info->tm_hour,info->tm_min);
		printf(" %s\n",pathname);

}
int main(int argc, const char *argv[])
{
	char pathname[20]="";
	printf("请输入文件路径以及名字:");
	scanf("%s",pathname);
	struct stat buf;
	if(stat(pathname,&buf) < 0)
		{
			ERRO_MES("stat");
			return -1;
		}
	if(S_ISDIR(buf.st_mode))
	{
		DIR *dp = opendir(pathname);
		if(NULL == dp)
		{
			ERRO_MES("opendir");
			return -1;
		}
		while(1)
		{
			struct dirent *rp=readdir(dp);
			if(NULL == rp)
			{
				if(0 == errno)
				{
					break;
				}
				else
				{
					ERRO_MES("readdir");
					return -1;
				}
			}
			
		get_file(rp->d_name);			
		//	printf("[%d]%s\n",++i,rp->d_name);
		}
	}
	else
	{
		DIR *dp = opendir(pathname);
		struct dirent *rp=readdir(dp);
		get_file(rp->d_name);			
	}
	return 0;
}

你可能感兴趣的:(网络,学习,开发语言)