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

用了这么长时间的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;
}


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

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

谢谢。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值