递归遍历目录


ls -R
可以遍历到目录里面的文件

思路

代码

/*************************************************************************
	> File Name: ls_R.c
	> Author: shaozheming
	> Mail: 957510530@qq.com
	> Created Time: 2022年02月25日 星期五 17时37分31秒
 ************************************************************************/

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define PATH_LEN 256

void fetchdir(const char *dir, void(*fcn)(char *)) //该函数被调用,既已判定为目录
{
	char name[PATH_LEN];
	struct dirent *sdp;
	DIR *dp;

	if((dp = opendir(dir)) == NULL){
		//打开目录失败
		fprintf(stderr, "fetchdir: can't open %s\n", dir);//报告错误位置的代码
		return ;
	}

	while((sdp = readdir(dp)) != NULL){
		if(strcmp(sdp->d_name, ".") == 0 || strcmp(sdp->d_name, "..") == 0){
			//防止出现无限递归
			//因为还有.和.. 拼接之后就又回到这个目录了
			continue;
		}

		if(strlen(dir) + strlen(sdp->d_name) + 2 > sizeof(name)){
			//代码判断,判断字符长度是不是大于256,,+2的意思是/和/0两个字符
			fprintf(stderr, "fetchdir: name %s %s too long\n", dir, sdp->d_name);
		} else {
			sprintf(name, "%s/%s", dir, sdp->d_name); //拼接成一个绝对路径
			(*fcn)(name);            
		}
	}
}


void isFile(char *name)   //处理目录/文件 
{
	struct stat sbuf;

	if(stat(name, &sbuf) == -1){ //文件名无效
		fprintf(stderr, "isfile: can't access %s\n", name);
		exit(1);
	}
	if((sbuf.st_mode & S_IFMT) == S_IFDIR){ //判断是否为目录
		fetchdir(name, isFile);				//回调函数
	}

	printf("%8ld %s\n", sbuf.st_size, name); //不是目录,则是普通文件,直接打印文件名字
}

int main(int argc, char* argv[])
{
	if(argc == 1)
		isFile(".");
	else
		while(--argc > 0)
			isFile(*++argv);
    return 0;
}