您的位置:首页 > 运维架构 > Linux

linux下用c语言实现ls -l 对文件或者目录的属性遍历

2014-08-07 21:44 686 查看
用了这么长时间的linux了,那么一个熟悉的不能再熟悉的命令 ls -l 是怎么实现的都不会的话,就很难在这个圈圈里面待了,就算待也会感觉不好意思的哦

呵呵 ,just kidding , 其实感觉如果可以把经常使用的命令自己都慢慢的用学到的语言去实现一遍的话,会是一件特别有趣的事情,不仅可以提高自己的编程能力,

又对linux有了更加深的认识,其乐融融啊。

温馨提示:

man的确是个好东西,虽然很多人对英语很头疼的吧,但是为了改变世界(传说程序员可以改变世界啊),就将就下咯。

直接奔向主题: 下面看代码的具体实现,主要是利用文件IO的一些函数,

用到的头文件直接封装在了head.h中了

见下图:






#include <head.h>

void display_file(const char *filename)//单个的显示一个文件的属性  ls  -l file
{
struct stat f_info;

if(stat(filename,&f_info) < 0)
{
fprintf(stderr,"@@File to stat %s:%s",filename,strerror(errno));
return ;
}

switch(f_info.st_mode & S_IFMT)  //文件的类型 b c d - l s p
{
case S_IFSOCK:
putchar('s');
break;
case S_IFLNK:
putchar('l');
break;
case S_IFDIR:
putchar('d');
break;
case S_IFCHR:
putchar('c');
break;
case S_IFBLK:
putchar('b');
break;
case S_IFREG:
putchar('-');
break;
case S_IFIFO:
putchar('p');
break;
default:
break;
}

#if 0/*{{{*/
//怎么优化 if  else ???
//主用户的权限
if(f_info.st_mode & S_IRUSR)
putchar('r');
else
putchar('-');
if(f_info.st_mode & S_IWUSR)
putchar('w');
else
putchar('-');
if(f_info.st_mode & S_IXUSR)
putchar('x');
else
putchar('-');
//用户组的权限
if(f_info.st_mode & S_IRGRP)
putchar('r');
else
putchar('-');
if(f_info.st_mode & S_IWGRP)
putchar('w');
else
putchar('-');
if(f_info.st_mode & S_IXGRP)
putchar('x');
else
putchar('-');
//其他人的权限
if(f_info.st_mode & S_IROTH)
putchar('r');
else
putchar('-');
if(f_info.st_mode & S_IWOTH)
putchar('w');
else
putchar('-');
if(f_info.st_mode & S_IXOTH)
putchar('x');
else
putchar('-');
#endif/*}}}*/

/************   if else   语句的优化   *****************/
int i;
int mov_n;
unsigned int mode;
for(mov_n = 6;mov_n >= 0;mov_n -=3)
{
mode = f_info.st_mode >> mov_n;
for(i = 2;i >= 0;i--)
{
switch(mode & ( 1 << i))
{
case 0:putchar('-');break;
case 1:putchar('x');break;
case 2:putchar('w');break;
case 4:putchar('r');break;
default:
break;
}
}
i = i-3;
}

/************   *******    *********      ***************/

//打印硬连接数
printf("%4d",f_info.st_nlink);

//打印用户名
printf("  %s",getpwuid(f_info.st_uid)->pw_name);

//打印组名
printf("  %s",getgrgid(f_info.st_gid)->gr_name);

//打印大小
printf(" %5ld",f_info.st_size);

//打印最后一次次改时间

time_t t;
struct tm  *ptm;   //利用到了time  与 localtime
t = f_info.st_atime;
ptm = localtime(&t);

printf("  %d %d %d  ",1+ptm->tm_mon,ptm->tm_mday,1900+ptm->tm_year);
printf("%d:%d ",ptm->tm_hour,ptm->tm_min);

printf("%s \n",filename);

return ;
}

<pre name="code" class="cpp">//显示目录中所有的文件
#if 1
void display_dir(const char *pathname)
{
DIR *dirp;
dirp = opendir(pathname); //打开一个目录的操作
if(dirp == NULL)
{
fprintf(stderr,"##File to opendir %s:%s\n",pathname,strerror(errno));
return ;
}

struct dirent *pdirent;
chdir(pathname);

while((pdirent = readdir(dirp)) != NULL)
{
if(pdirent->d_name[0] == '.')
continue;
//printf("%s \n",pdirent->d_name);//可以实现对任何目录名字的遍历
display_file(pdirent->d_name);  //可以实现对当前目录下文件的属性遍历
}
closedir(dirp);//关闭打开的目录
return ;
}
#endif



int main(int argc, const char *argv[])
{
if(argc < 2)
{
fprintf(stderr,"Uaage :%s argv[1]\n",argv[0]);
return -1;
}

//	display_file(argv[1]);//显示单个文件的属性

struct stat f_infor;

if(stat(argv[1],&f_infor) < 0)
{
fprintf(stderr,"$$File to stat %s:%s",argv[1],strerror(errno));
return -1;
}

#if 1
if( (f_infor.st_mode & S_IFMT) == S_IFDIR )
display_dir(argv[1]);
else
display_file(argv[1]);
#endif
return 0;
}


好了,上面的程序可以实现对任何的目录中的名字的遍历和对当前所在路径下的属性遍历,

肯定其中需要优化的地方和不足的地方,请各位大神给出指导性的建议,我会陆续的更新代码,

谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: