使用目录相关函数实现ls -l(不显示隐藏文件)
使用目录相关函数实现ls -l
首先通过观察ls -l
ls -l会显示文件的权限、所属用户、所属组、所占字节数、最近更新时间、文件名
通过stat函数即可得到所需信息。本次通过分装函数实现ls -l功能。
提取文件的权限
void s_mode(struct stat buf) // 获得文件权限信息
{
int i,m;
for(i=8;i>=0;i--)
{
m=(buf.st_mode&(1<<i))>>i;
switch(i%3)
{
case 2:
m==1?printf("r"):1;
break;
case 1:
m==1?printf("w"):1;
break;
case 0:
printf("———");
m==1?printf("x--"):1;
break;
}
}
}
获取文件所属用户
int get_usrname(uid_t uid) // 获取文件所属用户
{
struct passwd *pwd=getpwuid(uid);
if (NULL==pwd)
{
return -1;
}
printf(" %s ",pwd->pw_name);
return 0;
}
获取文件类型
int get_filetype(mode_t m) //获取文件类型
{
switch (m & S_IFMT)
{
case S_IFBLK: printf("b"); break;
case S_IFCHR: printf("c"); break;
case S_IFDIR: printf("d"); break;
case S_IFIFO: printf("p"); break;
case S_IFLNK: printf("l"); break;
case S_IFREG: printf("-"); break;
case S_IFSOCK: printf("s"); break;
default: printf("unknown?\n"); break;
}
return 0;
}
获得文件所属组
void get_grpname(gid_t gid) //获得文件所属组
{
struct group*grp=getgrgid(gid);
if (NULL==grp)
{
return ;
}
printf(" %s ",grp->gr_name);
}
获得文件最近修改时间
void get_time(time_t ctime) //获得文件最近修改时间
{
struct tm *info = localtime(&ctime);
printf(" %d-%02d-%02d %02d:%02d:%02d ",\
info->tm_year+1900, info->tm_mon+1, info->tm_mday,\
info->tm_hour, info->tm_min, info->tm_sec);
}
主函数
在主函数中通过外部参数定位目录及遍历目录中的文件,并进行函数调用
int main(int argc, const char *argv[])
{
DIR*dp= opendir(argv[1]);
if (NULL==dp)
{
return -1;
}
struct dirent*rp=NULL;
rp=readdir(dp); //获取目录信息
if (NULL==rp&&0!=errno)
{
return -1;
}
char x[50]; //用于存放地址
struct stat buf;
printf("目录读取完毕\n");
while(1)
{
rp=readdir(dp);
if (NULL==rp)
{
break;
}
if (rp->d_name[0]=='.')
{
continue;
}
strcpy(x,argv[1]);
strcat(x,rp->d_name); //用x存放文件的位置信息
if (stat(x,&buf)<0)
{
perror("stat");
return -1;
}
s_mode(buf);
get_usrname(buf.st_uid);
get_filetype(buf.st_mode);
get_grpname(buf.st_gid);
printf(" %ld ",buf.st_size);
get_time(buf.st_atime);
printf(" %s ",rp->d_name);
printf("\n");
//输出文件相关信息
}
closedir(dp);
return 0;
}
测试结果
测试当前目录
实现成功
测试其他目录
同样测试成功
虽然在格式上有欠缺但基本实现了ls -l的功能。
总代码
#include <stdio.h>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>
void s_mode(struct stat buf) // 获得文件权限信息
{
int i,m;
for(i=8;i>=0;i--)
{
m=(buf.st_mode&(1<<i))>>i;
switch(i%3)
{
case 2:
m==1?printf("r"):1;
break;
case 1:
m==1?printf("w"):1;
break;
case 0:
printf("———");
m==1?printf("x--"):1;
break;
}
}
}
int get_usrname(uid_t uid) // 获取文件所属用户
{
struct passwd *pwd=getpwuid(uid);
if (NULL==pwd)
{
return -1;
}
printf(" %s ",pwd->pw_name);
return 0;
}
int get_filetype(mode_t m) //获取文件类型
{
switch (m & S_IFMT)
{
case S_IFBLK: printf("b"); break;
case S_IFCHR: printf("c"); break;
case S_IFDIR: printf("d"); break;
case S_IFIFO: printf("p"); break;
case S_IFLNK: printf("l"); break;
case S_IFREG: printf("-"); break;
case S_IFSOCK: printf("s"); break;
default: printf("unknown?\n"); break;
}
return 0;
}
void get_grpname(gid_t gid) //获得文件所属组
{
struct group*grp=getgrgid(gid);
if (NULL==grp)
{
return ;
}
printf(" %s ",grp->gr_name);
}
void get_time(time_t ctime) //获得文件最近修改时间
{
struct tm *info = localtime(&ctime);
printf(" %d-%02d-%02d %02d:%02d:%02d ",\
info->tm_year+1900, info->tm_mon+1, info->tm_mday,\
info->tm_hour, info->tm_min, info->tm_sec);
}
int main(int argc, const char *argv[])
{
DIR*dp= opendir(argv[1]);
if (NULL==dp)
{
return -1;
}
struct dirent*rp=NULL;
rp=readdir(dp); //获取目录信息
if (NULL==rp&&0!=errno)
{
return -1;
}
char x[50]; //用于存放地址
struct stat buf;
printf("目录读取完毕\n");
while(1)
{
rp=readdir(dp);
if (NULL==rp)
{
break;
}
if (rp->d_name[0]=='.')
{
continue;
}
strcpy(x,argv[1]);
strcat(x,rp->d_name);//用x存放文件的位置信息
if (stat(x,&buf)<0)
{
perror("stat");
return -1;
}
s_mode(buf);
get_usrname(buf.st_uid);
get_filetype(buf.st_mode);
get_grpname(buf.st_gid);
printf(" %ld ",buf.st_size);
get_time(buf.st_atime);
printf(" %s ",rp->d_name);
printf("\n");
//输出文件相关信息
}
closedir(dp);
return 0;
}