使用C语言实现“ll“(查看文件详细信息)

小白第一篇

最近跟着大佬学习了文件IO,然后就被大佬安排使用C语言实现"ll"(查看文件详细信息)命令。

第一步:看需求

在这里插入图片描述
​ 由图可知,需要获取7列信息分别为:文件属性,文件硬链接数,文件拥有者,文件拥有者所在组,文件字节数,创建时间,文件名。

第二步 找方法

焦头烂额,也没想到有什么好方法,于是再次找上大佬。

佬:你傻啊,你可以使用lstat函数(一个可以获取文件信息的函数)。

我:???

佬:你不知道,你就去man它啊!光看着我有啥用。

于是:

man lstat

头文件如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

原函数如下:
int lstat(const char *pathname, struct stat *statbuf);

这对我也太友好了,看看有什么我能用上的:

struct stat {
    dev_t     st_dev;         /* ID of device containing file */
    ino_t     st_ino;         /* Inode number */
    mode_t    st_mode;        /* File type and mode 文件属性可用 */
    nlink_t   st_nlink;       /* Number of hard links 文件硬链接数可用 */
    uid_t     st_uid;         /* User ID of owner 文件拥有者可用 */
    gid_t     st_gid;         /* Group ID of owner 文件拥有者所在组可用 */
    dev_t     st_rdev;        /* Device ID (if special file) */
    off_t     st_size;        /* Total size, in bytes 文件字节数可用 */
    blksize_t st_blksize;     /* Block size for filesystem I/O */
    blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */
    
    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
};

第三步 写代码

1 文件属性

switch (sb.st_mode & S_IFMT) {
    case S_IFBLK:  printf("block device\n");            break;//判断是否为块设备文件
    case S_IFCHR:  printf("character device\n");        break;//判断是否为字符特殊文件
    case S_IFDIR:  printf("directory\n");               break;//判断是否为目录
    case S_IFIFO:  printf("FIFO/pipe\n");               break;//判断是否为管道文件
    case S_IFLNK:  printf("symlink\n");                 break;//判断是否为符号连接
    case S_IFREG:  printf("regular file\n");            break;//判断是否为普通文件
    case S_IFSOCK: printf("socket\n");                  break;//判断是否为套接字文件
    default:       printf("unknown?\n");                break;
}
//文件属性代码
switch(statbuf.st_mode & S_IFMT){//判断文件类型
    case S_IFSOCK:
        printf("s");
        break;
    case S_IFLNK:
        printf("l");
        break;
    case ......
        .....
        .....

就这样,就完成了第一列的第一小列。接下来,就需要判断文件的读写执行属性了。依旧是使用st_mode。

while(n >= 0){ 
    if(statbuf.st_mode & 1 << n){ 
        switch(n % 3){ 
            case 2:
                printf("r");
                break;
            case 1:
                printf("w");
                break;
            case 0:
                printf("x");
                break;
        }
    }
    else{
        printf("-");
    }
    n--;
}

2.文件硬链接数

//文件硬链接数代码
printf(" %ld",statbuf.st_nlink);

3.文件拥有者

由于文件提供了ID号给我,所以我需要getpwuid函数转换一下

#include <sys/types.h>
#include <pwd.h>

struct passwd *getpwuid(uid_t uid);

//文件拥有者代码
struct passwd *p_uid;
p_uid = getpwuid(statbuf.st_uid);
printf(" %s",p_uid->pw_name);

4.文件拥有者所在组

getgrgid()用法同getpwuid()

//文件拥有者所在组代码
struct group *p_gid;
p_gid = getgrgid(statbuf.st_gid);   
printf(" %s",p_gid->gr_name);

5.文件字节数

//文件字节数代码
printf("%7ld",statbuf.st_size);

6.创建时间

由于提供给我的时间是一个结构体,所以需要进行适当修改。
//创建时间代码
struct tm *tp = localtime(&statbuf.st_mtime);
printf(" %d月  %d %d:%02d",
       tp->tm_mon + 1,
       tp->tm_mday,
       tp->tm_hour,
       tp->tm_min);

至此,查询当前目录下的所有文件详细信息就完成了。


大佬:什么?只能查询当前目录,那有何用。

我:好的好的,我改.......

回头看看需求,我这次是要去其他目录,这次我学聪明了,就先进行了"学习"。

先B了一下
在这里插入图片描述

再C了一下
在这里插入图片描述

就这样,我学了一个新的函数,叫做readdir()

man readdir

#include <dirent.h>

struct dirent *readdir(DIR *dirp);

//目录读取代码
DIR * dir;
struct dirent * ptr;
dir = opendir(argv[1]);
char str[20];
while((ptr = readdir(dir)) != NULL){
    strcpy(str,argv[1]);
    strcat(str,"/");//路径必备 “/”
    get_stat(strcat(str,ptr->d_name));//将文件信息封装成了函数
    printf(" %s\n",ptr->d_name);//文件名

·······························································最后的结果是这样的··································································
在这里插入图片描述
············································································和这样的···································································
在这里插入图片描述

我兴高采烈的拿去给大佬看,然后,
佬:还不错,能做出来,但你自己回去还是再想哈,为什么还有这样的?

在这里插入图片描述

写在结尾:我还没想通,有知道原因且愿意告知的请告知,谢谢。再次欢迎各位大佬批评改正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值