该函数的作用是读取指定目录下的所有文件和子目录,并将满足条件的文件拷贝到指定目录中。

以下是对每行代码的解释:

  1. struct stat pstat; :定义一个用于保存文件属性的结构体变量。

  2. struct arg *arg1; :定义一个指向arg结构体的指针变量。

  3. char path1[1024];char path2[1024]; :定义两个用于保存路径的字符数组。

  4. int ret; :定义一个用于保存函数返回值的变量。

  5. DIR *p=opendir(dirpath); :打开指定路径的目录,并返回一个指向DIR结构体的指针。

  6. if(p==NULL) :判断目录是否打开成功,如果打开失败,则输出错误信息并返回-1。

  7. struct dirent *mydir; :定义一个指向dirent结构体的指针变量,用于保存每个目录项的信息。

  8. while((mydir=readdir(p))!=NULL) :循环读取目录下的每个目录项,直到读取完所有目录项。

  9. bzero(path1,1024);bzero(path2,1024); :将path1和path2数组清零。

  10. if(strcmp(mydir->d_name,".")==0 || strcmp(mydir->d_name,"..")==0) :判断目录项的名称是否为'.'或'...',如果是,则跳过该目录项。

  11. if(mydir->d_type==DT_DIR) :判断目录项的类型是否为目录文件。

  12. sprintf(path1,"%s/%s",newpath,mydir->d_name); :将新建目录的路径名拼接起来。

  13. int ret = mkdir(path1,0777); :创建目录,权限为0777。

  14. if(ret==-1) :判断目录创建是否成功,如果失败则输出错误信息。

  15. bzero(path2,1024); :将path2数组清零。

  16. sprintf(path2,"%s/%s",dirpath,mydir->d_name); :将原始目录的路径名拼接起来。

  17. myreaddir(pool,path2,path1,type); :递归调用myreaddir函数,继续读取子目录的内容。

  18. if(mydir->d_type==DT_REG) :判断目录项的类型是否为普通文件。

  19. if(strstr(type,"all")!=NULL) :判断是否需要拷贝所有的普通文件。

  20. arg1=malloc(sizeof(struct arg)); :为arg1变量分配内存。

  21. sprintf(path1,"%s/%s",dirpath,mydir->d_name); :将原始文件的路径名拼接起来。

  22. sprintf(path2,"%s/%s",newpath,mydir->d_name); :将新建文件的路径名拼接起来。

  23. strcpy(arg1->oldpath,path1);strcpy(arg1->newpath,path2); :将路径名拷贝到arg1结构体中。

  24. add_task(mycopy,arg1,pool); :将任务添加到任务链表中,任务函数为mycopy。

  25. ret=stat(path1,&pstat); :获取原始文件的属性信息。

  26. if(ret==-1) :判断获取属性信息是否成功,如果失败则输出错误信息。

  27. totsize=totsize+pstat.st_size; :计算文件大小。

  28. closedir(p); :关闭目录。

  29. return 0; :返回0,表示函数执行成功。


**代码示例**

```c
int myreaddir(struct threadpool *pool,char *dirpath,char *newpath,char *type)
{
	struct stat pstat; //文件属性变量
	struct arg *arg1;  //arg结构体
	char path1[1024];  
	char path2[1024];
	int ret;
	
	//打开目录
	DIR *p=opendir(dirpath); 
	if(p==NULL)
	{
		perror("打开目录失败!\n");
		return -1;
	}
	
	//循环读取目录
	struct dirent *mydir;
	while((mydir=readdir(p))!=NULL)
	{
		//清空数组
		bzero(path1,1024);
		bzero(path2,1024);
		
		//排除调用.和..
		//if(strncmp(mydir->d_name,".",1)==0) 
		if(strcmp(mydir->d_name,".")==0 || strcmp(mydir->d_name,"..")==0) 	
			continue;
		
		if(mydir->d_type==DT_DIR) //目录文件
		{
			sprintf(path1,"%s/%s",newpath,mydir->d_name);//拼接新建的目录
		
			//创建目录
			int ret = mkdir(path1,0777);
			if(ret==-1)
			{
				perror("新建目录失败");
			}
			
			//递归调用自己,接着读取子目录
			bzero(path2,1024);
			sprintf(path2,"%s/%s",dirpath,mydir->d_name);
			myreaddir(pool,path2,path1,type);
		}
		
		if(mydir->d_type==DT_REG)//普通文件
		{
			if(strstr(type,"all")!=NULL)//全部普通文件拷贝
			{
				arg1=malloc(sizeof(struct arg));
				sprintf(path1,"%s/%s",dirpath,mydir->d_name);   //拼接原本普通文件的路径名
				sprintf(path2,"%s/%s",newpath,mydir->d_name);   //拼接新建文件的路径名
				strcpy(arg1->oldpath,path1);
				strcpy(arg1->newpath,path2);
				add_task(mycopy,arg1,pool);//加进任务链表
				ret=stat(path1,&pstat);//获取属性信息
				if(ret==-1)
				{
					printf("获取属性信息失败!\n");
					return -1;
				}
				totsize=totsize+pstat.st_size;;//计算文件大小
			}
			else  if(strstr(mydir->d_name,type)!=NULL && strstr(type,"all")==NULL) ////type类型文件拷贝
			{		
				arg1=malloc(sizeof(struct arg));
				sprintf(path1,"%s/%s",dirpath,mydir->d_name);   //拼接原本文件的路径名
				sprintf(path2,"%s/%s",newpath,mydir->d_name);   //拼接新建文件的路径名
				strcpy(arg1->oldpath,path1);
				strcpy(arg1->newpath,path2);
				add_task(mycopy,arg1,pool);//加进任务链表
				ret=stat(path1,&pstat);//获取属性信息
				if(ret==-1)
				{
					printf("获取属性信息失败!\n");
					return -1;
				}
				totsize=totsize+pstat.st_size;//计算文件大小
			}	
			
		} 
		
	}
	//关闭目录
	closedir(p);
	return 0;
}
C语言函数 myreaddir:递归遍历目录并拷贝文件

原文地址: https://www.cveoy.top/t/topic/oehO 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录