C语言函数 myreaddir:递归遍历目录并拷贝文件
该函数的作用是读取指定目录下的所有文件和子目录,并将满足条件的文件拷贝到指定目录中。
以下是对每行代码的解释:
-
struct stat pstat;:定义一个用于保存文件属性的结构体变量。 -
struct arg *arg1;:定义一个指向arg结构体的指针变量。 -
char path1[1024];和char path2[1024];:定义两个用于保存路径的字符数组。 -
int ret;:定义一个用于保存函数返回值的变量。 -
DIR *p=opendir(dirpath);:打开指定路径的目录,并返回一个指向DIR结构体的指针。 -
if(p==NULL):判断目录是否打开成功,如果打开失败,则输出错误信息并返回-1。 -
struct dirent *mydir;:定义一个指向dirent结构体的指针变量,用于保存每个目录项的信息。 -
while((mydir=readdir(p))!=NULL):循环读取目录下的每个目录项,直到读取完所有目录项。 -
bzero(path1,1024);和bzero(path2,1024);:将path1和path2数组清零。 -
if(strcmp(mydir->d_name,".")==0 || strcmp(mydir->d_name,"..")==0):判断目录项的名称是否为'.'或'...',如果是,则跳过该目录项。 -
if(mydir->d_type==DT_DIR):判断目录项的类型是否为目录文件。 -
sprintf(path1,"%s/%s",newpath,mydir->d_name);:将新建目录的路径名拼接起来。 -
int ret = mkdir(path1,0777);:创建目录,权限为0777。 -
if(ret==-1):判断目录创建是否成功,如果失败则输出错误信息。 -
bzero(path2,1024);:将path2数组清零。 -
sprintf(path2,"%s/%s",dirpath,mydir->d_name);:将原始目录的路径名拼接起来。 -
myreaddir(pool,path2,path1,type);:递归调用myreaddir函数,继续读取子目录的内容。 -
if(mydir->d_type==DT_REG):判断目录项的类型是否为普通文件。 -
if(strstr(type,"all")!=NULL):判断是否需要拷贝所有的普通文件。 -
arg1=malloc(sizeof(struct arg));:为arg1变量分配内存。 -
sprintf(path1,"%s/%s",dirpath,mydir->d_name);:将原始文件的路径名拼接起来。 -
sprintf(path2,"%s/%s",newpath,mydir->d_name);:将新建文件的路径名拼接起来。 -
strcpy(arg1->oldpath,path1);和strcpy(arg1->newpath,path2);:将路径名拷贝到arg1结构体中。 -
add_task(mycopy,arg1,pool);:将任务添加到任务链表中,任务函数为mycopy。 -
ret=stat(path1,&pstat);:获取原始文件的属性信息。 -
if(ret==-1):判断获取属性信息是否成功,如果失败则输出错误信息。 -
totsize=totsize+pstat.st_size;:计算文件大小。 -
closedir(p);:关闭目录。 -
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;
}
原文地址: https://www.cveoy.top/t/topic/oehO 著作权归作者所有。请勿转载和采集!