目录IO及小练习

一、目录操作函数

opendir  打开目录
readdir  读目录文件
closedir 关闭目录
chdir 修改当前所处路径

1、打开目录:opendir

  #include <sys/types.h>
  #include <dirent.h>
  DIR *opendir(const char *name);
  功能:打开目录文件
  参数:name:文件名
返回值:成功返回目录流指针,失败NULL,更新error

2、closedir 关闭目录2

  #include <sys/types.h>
  #include <dirent.h>
  int closedir(DIR *dirp);
   功能:关闭目录
   参数:dirp:目录流指针
   返回值:成功0,失败-1,更新errno

3、readdir  读目录文件

  #include <sys/types.h>
  #include <dirent.h>
  struct dirent *readdir(DIR *dirp);
    功能:读目录文件
    参数:dirp:目录流指针
    返回值:成功返回结构体指针,读到文件结尾返回NULL
         失败NULL,更新errno
 struct dirent 
     {
     ino_t          d_ino;       /*文件的inode */
     off_t          d_off;       /* not an offset; see NOTES */
     unsigned short d_reclen;    /* 记录的长度 */
     unsigned char  d_type;      /* 文件类型,并不支持所有文件类型*/
     char           d_name[256]; /* filename */
     }       

练习实现ls功能

#include<stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc, char const *argv[])
{
    struct dirent *dir;//创建结构体
    DIR *dirp = opendir(argv[1]);//打开文件
    if(dirp == NULL)//容错
    {
        perror(" opendir err");
        return -1;
    }
    while ((dir = readdir(dirp)) != NULL)//读取目录文件
    {
        if(dir->d_name[0]=='.')
        continue;
        printf("%s ",dir->d_name);//输出目录内容
    }
    puts(" ");
    closedir(dirp);//关闭文件目录流
    return 0;
}

4、chdir 修改当前所处路径

#include <unistd.h>
int chdir(const char *path);
     功能:改变当前所处的路径
	 参数:path:修改的路径、
	 返回值:成功0
	      失败:-1,更新errno

二、获取文件属性函数stat

stat :显示文件或文件系统状态
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *buf);
功能:获取文件属性
参数:pathname:文件路径名
       buf:保存文件属性信息的结构体
返回值:成功:0
      失败:-1 更新error
struct stat 
    {
        dev_t     st_dev;         /* 设备包含文件ID */
        ino_t     st_ino;     /* inode号 */
        mode_t    st_mode;    /* 文件类型和权限 */
        nlink_t   st_nlink;   /* 硬链接数 */
        uid_t     st_uid;     /* 用户ID */
        gid_t     st_gid;     /* 组ID */
        off_t     st_size;    /* 大小 */
        dev_t     st_rdev;        /* 设备ID */
        time_t    st_atime;   /* 最后访问时间 */
        time_t    st_mtime;   /* 最后修改时间 */
        time_t    st_ctime;  /* 最后状态改变时间 */
    };

 st_mode 包含的是文件类型和权限:
    文件类型:
 S_IFMT     0170000   bit mask for the file type bit field
 S_IFSOCK   0140000   socket-套接字 S
 S_IFLNK    0120000   symbolic link-连接文件L
 S_IFREG    0100000   regular file-普通文件 -
 S_IFBLK    0060000   block device块设备b
 S_IFDIR    0040000   directory目录 d
 S_IFCHR    0020000   character 字符设备 c
 S_IFIFO    0010000   FIFO管道 p
 
 使用规则:
 stat(pathname, &sb);
if ((sb.st_mode & S_IFMT) == S_IFREG) {
    /* Handle regular file */
}
    将使用规则封装:封装成宏函数
  S_ISREG(m)  is it a regular file?
  S_ISDIR(m)  directory?
  S_ISCHR(m)  character device?
  S_ISBLK(m)  block device?
  S_ISFIFO(m) FIFO (named pipe)?
  S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)
  S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

权限:后九位控制权限
 S_IRUSR     00400   owner has read permission
 S_IWUSR     00200   owner has write permission
 S_IXUSR     00100   owner has execute permission

 S_IRGRP     00040   group has read permission
 S_IWGRP     00020   group has write permission
 S_IXGRP     00010   group has execute permission

 S_IROTH     00004   others have read permission
 S_IWOTH     00002   others have write permission
 S_IXOTH     00001   others have execute permission


 1.getpwuid:通过用户id获取用户名
 struct passwd *getpwuid(uid_t uid);
 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 */
     };

  2.getgrgid:通过组id获取组名
  struct group *getgrgid(gid_t gid);
  struct group 
  {
      char   *gr_name;       /* group name */
      char   *gr_passwd;     /* group password */
      gid_t   gr_gid;        /* group ID */
      char  **gr_mem;        /* group members */
  };  
3. ctime();将时间转转换为字符串表示格式
char *ctime(const time_t *timep);
如:转换为-"Wed Jun 30 21:49:08 1993\n"

练习:用目录IO函数实现ls -l 和ls -i功能

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include<time.h>
#include <dirent.h>
#include<string.h>
void Show(char *file)
{
    struct stat sb;
    stat(file,&sb);
    switch(sb.st_mode & __S_IFMT)
    {
        case __S_IFSOCK:printf("s");break;
        case __S_IFLNK:printf("l");break;
        case __S_IFREG:printf("-");break;
        case __S_IFBLK:printf("b");break;
        case __S_IFDIR:printf("d");break;
        case __S_IFCHR:printf("c");break;
        case __S_IFIFO:printf("p");break;
        default:break ;
    }
    //法1
    // char bus[3]="rwx";
    // for(int i=0;i<9;i++)
    // sb.st_mode & (0400>>i)?printf("%c",bus[i%3]):printf("-");
    //法2
    for(int i = 8;i>=0;i--)
    {
        if(sb.st_mode & (1<<i))
        {
            if(i == 8||i == 5||i == 2)
            printf("r");
            if(i == 7||i == 4||i == 1)
            printf("w");
            if(i == 6||i == 3||i == 0)
            printf("x");
        }
        else
        {
            printf("-");
        }
        
    }
    #if 0//法3
    //用户权限
    if(sb.st_mode & (1<<8))
    printf("r");
    else
    {
        printf("-");
    }
    if(sb.st_mode & (1<<7))
    printf("w");
    else
    {
        printf("-");
    }
    if(sb.st_mode & (1<<6))
    printf("x");
    else
    {
        printf("-");
    }
        //组用户权限
    if(sb.st_mode & (1<<5))
    printf("r");
    else
    {
        printf("-");
    }
    if(sb.st_mode & (1<<4))
    printf("w");
    else
    {
        printf("-");
    }
    if(sb.st_mode & (1<<3))
    printf("x");
    else
    {
        printf("-");
    }
        //其他用户权限
    if(sb.st_mode & (1<<2))
    printf("r");
    else
    {
        printf("-");
    }
    if(sb.st_mode & (1<<1))
    printf("w");
    else
    {
        printf("-");
    }
    if(sb.st_mode & (1<<0))
    printf("x");
    else
    {
        printf("-");
    }
    #endif
    printf(" %u",sb.st_nlink);
    struct passwd *uname = getpwuid(sb.st_uid);
    struct group *gname = getgrgid(sb.st_gid);
    printf(" %s",gname->gr_name);//用户名
    printf(" %s",uname->pw_name);//组用户名
    printf(" %ld",sb.st_size);
    printf(" %.12s",4+ctime(&sb.st_mtime));
    printf(" %s",file);
    puts(" ");
}
int main(int argc, char const *argv[])
{
    struct dirent *dir;//创建结构体

    DIR *dirp = opendir("./");//打开文件
    if(dirp == NULL)//容错
    {
        perror(" opendir err");
        return -1;
    }
    if(!strncmp(argv[1],"-l",2))//判断输入的命令
    {
        while ((dir = readdir(dirp)) != NULL)//读取目录文件
        {
            if(dir->d_name[0]=='.')
            continue;
            Show(dir->d_name);
        }
    }
    else if (!strncmp(argv[1],"-i",2))
    {
        struct stat sb;
        stat(dir->d_name,&sb);
            while ((dir = readdir(dirp)) != NULL)//读取目录文件
        {
            if(dir->d_name[0]=='.')
            continue;
            stat(dir->d_name,&sb);
            printf("%-7ld",sb.st_ino);
            printf("%-13s",dir->d_name);//输出目录内容
        }
        puts(" ");
    }
    closedir(dirp);//关闭文件目录流
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

满山的猴子我的腚最红

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值