基于linux与线程池实现文件管理


项目要求

1.基本

  用线程池实现一个大文件夹的拷贝,大文件夹嵌套很多小文件;实现复制到指定文件夹的全部文件夹。

2.扩充功能

  显示进度条;拷贝耗时统计;类似linux的tree,不能直接用system()与exec()等函数;根据文件类型拷贝;搜索文件;删除文件等。(暂时加了这么一些功能)

8月17日补:移动、复制到的目录已包含该文件则选择覆盖或者加命名。

实现思路

  先完成基本,逐步完成扩展再优化重构代码。

实现过程

基本功能

  基于linux,通过线程池实现的。核心就是线程池的三大基本功能--线程例程、添加线程、销毁线程池。由这三个为基础,对项目进行展开。基本功能,即通过递归读取目录,通过strucr dirent *p这个结构体来实现判断文件类型。如果是普通文件,直接在新目录用文件IO的读写实现拷贝功能(包括标准IO、系统IO,还有共享内存也可以实现),拷贝那里用“添加线程”,保证可以多线程实现拷贝;如果是目录文件,就先创建文件夹--mkdir(),再sprintf拼接字符串以及函数的递归实现子级目录的拷贝。

->拷贝代码

void *myregcp(void *myarg)
{
    struct copypath *mypath=(struct copypath *)myarg;
    
    //系统IO的复制
    int fd1,fd2;
    fd1=open(mypath->oldpath,O_RDONLY);
    fd2=open(mypath->newpath,O_CREAT|O_TRUNC|O_RDWR,0777);
    if(fd1==-1)
    {
        perror("打开1失败\n");
        return NULL;
    }
    if(fd2==-1)
    {
        perror("打开2失败\n");
        return NULL;
    }
    char buf[SIZE];
    int nread,nwrite;
    while(1)
    {
        bzero(buf,SIZE);
        nread=read(fd1,buf,SIZE);
        if(nread==0)
            break;
        cs=cs+nread;
        write(fd2,buf,nread);
    }
    close(fd1);
    close(fd2);    
    return NULL;    
}

->递归读取全部目录

int myreaddir(struct copypath *pp,struct threadpool *pool)
{
    DIR *dirp=opendir(pp->oldpath);
    if(dirp==NULL)
    {
        perror("失败:\n");
        return -1;
    }
    struct dirent *p;    
    while((p=readdir(dirp))!=NULL)
    {    
        if(p->d_type==DT_REG)        //普通文件
        {
            struct copypath *mypath=malloc(sizeof(struct copypath));
            sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
            sprintf(mypath->newpath,"%s/%s",pp->newpath,p->d_name);
            add_task(myregcp,mypath,pool);    //实现
        }
        if(p->d_type==DT_DIR)        //文件夹
        {                
            if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
            {    
                struct copypath *mydirpath=malloc(sizeof(struct copypath));
                sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
                sprintf(mydirpath->newpath,"%s/%s",pp->newpath,p->d_name);
                mkdir(mydirpath->newpath,0777);
                myreaddir(mydirpath,pool);
            }
        }
    }
    closedir(dirp);
    return 1;
}

  这样就大概完成基本功能,用多线程实现大文件夹的拷贝。

扩充功能

->进度条

  定义两个全局变量,一个用于计算总字节数,另一个计算每次复制的字节数,再用一个显示函数实现进度条的显示。这里要注意缓冲区的问题,所以我用了"fflush(NULL)"这个函数,让它每打印一个'|'的时候,就刷新一次缓冲区。计算总的字节数直接递归全部目录,用"struct stat info"这个结构体里面的"info.st_size"累加,即可得到总的字节数;拷贝功能函数里面有个"cs"变量,就是存放拷贝字节数。显示进度条就用简单的判断,加相除实现。因为是显示20个|,所以我乘20。

  num=(float)cs;        //正在复制字节数
  k=(num/s)*20;    

->耗时

  有三种思路,用clock()、time()、sleep(1)等都可以实现计时,直接在拷贝前和拷贝后加赋值,然后相减,即可。起初自己是用clock()这个函数,但是每次都是三秒。。。然后转到sleep(),让它自己while()累加实现。

->代码实现树

  还是递归的思想,递归如果是普通文件就打印,是目录文件夹就字符串拼接再递归打印子文件夹下的子文件。

void dirtree(char dirpath[],int level)
{
    int i;
    char *dirname=NULL;
    int dirlen;
    DIR *dp=opendir(dirpath);
    if(dp==NULL)
    {
        perror("失败:\n");
        return;
    }
    struct dirent *ep;
    while((ep=readdir(dp))!=NULL)
    {
        if(strncmp(ep->d_name, ".", 1) == 0)
            continue;
        for(i=0;i)
        {
            printf("|");
            printf("     ");
        }
        printf("|--- ");
        printf("\033[1;32;40m %s \033[0m\n",ep->d_name);
        if(ep->d_type==DT_DIR)
        {
            //当前目录长度
            dirlen=strlen(dirpath)+1;
            //备份
            dirname=(char *)malloc(dirlen);
            memset(dirname,0,dirlen);
            memcpy(dirname,dirpath,dirlen);
            
            strcat(dirpath,"/");
            strcat(dirpath,ep->d_name);
            dirtree(dirpath,level+1);        //递归实现树效果
            //恢复之前的目录名
            memcpy(dirpath,dirname,dirlen);
            free(dirname);            
            dirname = NULL;
        }
    }    
    closedir(dp);
}

->按类型拷贝文件

  也比较简单,另建一个递归读目录的函数,在普通文件加个if条件判断就可以。

  if(strstr(p->d_name,ftype)!=NULL)

->搜索文件

  类似于win的文件检索功能,在输入那个文件下面实现相似文件名的检索,并打印相关路径。也是递归读取目录,核心的改变代码也就一句。用"strstr()"寻找相应的子字符串,打印。

  if(strstr(p->d_name,filename)!=NULL)

->删除文件夹

  删除稍微要注意一下如果文件夹下面还有其他文件,就不能直接用"rmdir"删除文件夹。先用remove()删除文件,之后再删除子文件夹。也是用递归思想实现的。

实现效果

  现在还传不了,后期再传吧。

全部代码

#include "myhead.h"
#define SIZE 1024*1024
long int s=0;    //总字节数
long int cs=0;    //计算每次复制的字节数
int tm=0;        //计时--以秒为单位
int flag;        //结束标志位
/***************************相关结构体的定义******************************/
struct copypath
{
    char oldpath[256];
    char newpath[256];
    char target[50];
};
//创建任务链表结构体
struct tasklist
{
    void *(*taskp)(void *);
    void *taskarg;
    struct tasklist *next;
};
//创建任务链表表头
struct tasklist *myhead;
//初始化任务链表
struct tasklist* task_init()
{    
    struct tasklist *mytask=malloc(sizeof(struct tasklist));
    mytask->taskp=NULL;
    mytask->taskarg=NULL;
    mytask->next=NULL;
    return mytask;
}
//创建线程池
struct threadpool
{
    int threadnum;//统计当前线程数量
    pthread_t *threadid;//存放当前线程的ID号
    struct tasklist *taskhead;//保存任务链表的头结点
    pthread_mutex_t threadmutex;//互斥锁
    int tasknum;//统计任务链表中的数量
    pthread_cond_t threadcond;//条件变量
    bool threadflag;//用于判断线程池是否开启
};

//线程的多任务函数
void *routine(void *arg)
{
    struct threadpool *pool=(struct threadpool *)arg;
    //负责从任务链表的头结点的下一个位置取出任务然后处理
    struct tasklist *p;
    while(1)
    {
        //上锁
        pthread_mutex_lock(&(pool->threadmutex));
        //判断数量是否为0
        while(pool->threadflag==true && pool->tasknum==0)
        {
            //printf("%ld线程阻塞--wait\n",pthread_self());
            pthread_cond_wait(&(pool->threadcond),&(pool->threadmutex));
        }
        if(pool->threadflag==false&&pool->tasknum==0)
        {
            pthread_mutex_unlock(&(pool->threadmutex));
            pthread_exit(NULL);
        }
        //取出节点处理
        p=pool->taskhead->next;
        pool->taskhead->next=p->next;
        p->next=NULL;
        //更新任务数量
        pool->tasknum--;
        //printf("%ld线程正在执行任务\n",pthread_self());
        //解锁
        pthread_mutex_unlock(&(pool->threadmutex));
        (p->taskp)(p->taskarg);
        free(p);
    }
}
//初始化线程池结构体
struct threadpool *thread_init(int num)
{
    struct threadpool *mythread=malloc(sizeof(struct threadpool));//申请堆空间
    mythread->threadnum=num;
    mythread->threadid=malloc(num*sizeof(pthread_t));
    //初始化链表的表头
    mythread->taskhead=myhead;
    //锁初始化
    pthread_mutex_init(&(mythread->threadmutex),NULL);
    //条件变量初始化
    pthread_cond_init(&(mythread->threadcond),NULL);
    mythread->tasknum=0;
    mythread->threadflag=true;
    for(int i=0;i)
        pthread_create(&(mythread->threadid[i]),NULL,routine,mythread);
    return mythread;
}
//添加任务函数
int add_task(void *(*p)(void *),void *newarg,struct threadpool *pool)
{
    //找到尾部
    struct tasklist *q=pool->taskhead;
    while(q->next!=NULL)
        q=q->next;
    //准备新结点
    struct tasklist *newnode=malloc(sizeof(struct tasklist));
    newnode->taskp=p;
    newnode->taskarg=newarg;
    newnode->next=NULL;
    
    //上锁
    pthread_mutex_lock(&(pool->threadmutex));
    //尾插
    q->next=newnode;
    //更新任务数量
    pool->tasknum++;
    pthread_mutex_unlock(&(pool->threadmutex));
    //唤醒条件
    pthread_cond_signal(&(pool->threadcond));
    return 0;    
}
/***************************************************************************/
//                                功能函数
/***************************************************************************/
//主目录名
void *mycopyname(void *myarg)
{
    struct copypath *mypath=(struct copypath *)myarg;
    char fpath[15];    //求出主目录的名字
    char temp[100];
    strcpy(temp,mypath->oldpath);
    char *p=strtok(temp,"/");
    //获取文件名
    while(p!=NULL)
    {
        bzero(fpath,15);
        strcpy(fpath,p);
        p=strtok(NULL,"/");
    }
    strcpy(((struct copypath *)myarg)->target,fpath);
}
//普通文件复制
void *myregcp(void *myarg)
{
    struct copypath *mypath=(struct copypath *)myarg;
    
    //系统IO的复制
    int fd1,fd2;
    fd1=open(mypath->oldpath,O_RDONLY);
    fd2=open(mypath->newpath,O_CREAT|O_TRUNC|O_RDWR,0777);
    if(fd1==-1)
    {
        perror("打开1失败\n");
        return NULL;
    }
    if(fd2==-1)
    {
        perror("打开2失败\n");
        return NULL;
    }
    char buf[SIZE];
    int nread,nwrite;
    while(1)
    {
        bzero(buf,SIZE);
        nread=read(fd1,buf,SIZE);
        //cs=cs+nread;
        if(nread==0)
            break;
        cs=cs+nread;
        write(fd2,buf,nread);
    }
    close(fd1);
    close(fd2);    
    return NULL;    
}
//遍历读目录
int myreaddir(struct copypath *pp,struct threadpool *pool)
{
    DIR *dirp=opendir(pp->oldpath);
    if(dirp==NULL)
    {
        perror("失败:\n");
        return -1;
    }
    struct dirent *p;    
    while((p=readdir(dirp))!=NULL)
    {    
        if(p->d_type==DT_REG)        //普通文件
        {
            struct copypath *mypath=malloc(sizeof(struct copypath));
            sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
            sprintf(mypath->newpath,"%s/%s",pp->newpath,p->d_name);
            add_task(myregcp,mypath,pool);    //实现
        }
        if(p->d_type==DT_DIR)        //文件夹
        {                
            if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
            {    
                struct copypath *mydirpath=malloc(sizeof(struct copypath));
                sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
                sprintf(mydirpath->newpath,"%s/%s",pp->newpath,p->d_name);
                mkdir(mydirpath->newpath,0777);
                myreaddir(mydirpath,pool);
            }
        }
    }
    closedir(dirp);
    return 1;
}
//递归算字节数
int size_sum(struct copypath *pp)
{
    DIR *dirp=opendir(pp->oldpath);
    if(dirp==NULL)
    {
        perror("失败:\n");
        return -1;
    }
    struct dirent *p;
    struct stat info;
    while((p=readdir(dirp))!=NULL)
    {    
        if(p->d_type==DT_REG)        //普通文件
        {
            struct copypath *mypath=malloc(sizeof(struct copypath));
            sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
            //计算字节数
            stat(mypath->oldpath,&info);
            s=s+info.st_size;
        }
        if(p->d_type==DT_DIR)        //文件夹
        {                
            if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
            {    
                struct copypath *mydirpath=malloc(sizeof(struct copypath));
                sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
                size_sum(mydirpath);
            }
        }
    }
    closedir(dirp);
    return 1;
}
//实现进度条
void *pro_bar(void *myarg)
{
    int i,j=0;
    float k,num;
    printf("进度:");
    while(1)
    {
        j=k;
        num=(float)cs;        //正在复制字节数
        k=(num/s)*20;        //
        k=(int)k;        
        if(k-j>=1)
        {
            for(i=0;i)        
            {                
                printf("\033[1;31;42m | \033[0m");
            }
            fflush(NULL);
        }
        usleep(10000);
        if(s==cs)
        {
            printf("\033[1;31;42m | \033[0m");
            fflush(NULL);
            usleep(200);
            break;
        }            
    }
    printf("\n任务完成\n");
    return NULL;
}
//lseep计时
void *my_time(void *myarg)
{
    while(1)
    {
        sleep(1);
        tm++;
        if(s==cs)
        {
            break;
        }
    }
}
//显示选择拷贝类型界面
int showdow()
{
    int n;
    printf("**********************\n");
    printf(" 请输入你要拷贝的文件 \n");
    printf("   1.复制全部文件;    \n");
    printf("   2.选择类型复制;    \n");
    printf("   3.原目录文件树;    \n");
    printf("   4.查找某个文件;   \n");
    printf("   5.删除某个文件.    \n");
    printf("**********************\n");
    scanf("%d",&n);
    return n;
}
//递归读取文件类型的字节数
int ftypesize_sum(struct copypath *pp,char *ftype)
{
    DIR *dirp=opendir(pp->oldpath);
    if(dirp==NULL)
    {
        perror("失败:\n");
        return -1;
    }
    struct dirent *p;
    struct stat info;
    while((p=readdir(dirp))!=NULL)
    {    
        if(p->d_type==DT_REG)        //普通文件
        {
            if(strstr(p->d_name,ftype)!=NULL)    //文件类型
            {
                struct copypath *mypath=malloc(sizeof(struct copypath));
                sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
                //计算字节数
                stat(mypath->oldpath,&info);
                s=s+info.st_size;
            }            
        }
        if(p->d_type==DT_DIR)        //文件夹
        {    
            if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
            {    
                struct copypath *mydirpath=malloc(sizeof(struct copypath));
                sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
                ftypesize_sum(mydirpath,ftype);
            }
        }
    }
    closedir(dirp);
    return 1;    
}
//递归读取文件类型的目录
int myftyper(struct copypath *pp,struct threadpool *pool,char *ftype)
{
    DIR *dirp=opendir(pp->oldpath);
    if(dirp==NULL)
    {
        perror("失败:\n");
        return -1;
    }
    struct dirent *p;
    while((p=readdir(dirp))!=NULL)
    {    
        if(p->d_type==DT_REG)        //普通文件
        {
            if(strstr(p->d_name,ftype)!=NULL)
            {
                struct copypath *mypath=malloc(sizeof(struct copypath));
                sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
                sprintf(mypath->newpath,"%s/%s",pp->newpath,p->d_name);
                add_task(myregcp,mypath,pool);    //实现
            }
        }
        if(p->d_type==DT_DIR)        //文件夹
        {                
            if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
            {    
                struct copypath *mydirpath=malloc(sizeof(struct copypath));
                sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
                sprintf(mydirpath->newpath,"%s/%s",pp->newpath,p->d_name);
                mkdir(mydirpath->newpath,0777);
                myftyper(mydirpath,pool,ftype);
            }
        }
    }
    closedir(dirp);
    return 1;
}
//树实现
void dirtree(char dirpath[],int level)
{
    int i;
    char *dirname=NULL;
    int dirlen;
    DIR *dp=opendir(dirpath);
    if(dp==NULL)
    {
        perror("失败:\n");
        return;
    }
    struct dirent *ep;
    while((ep=readdir(dp))!=NULL)
    {
        if(strncmp(ep->d_name, ".", 1) == 0)
            continue;
        for(i=0;i)
        {
            printf("|");
            printf("     ");
        }
        printf("|--- ");
        printf("\033[1;32;40m %s \033[0m\n",ep->d_name);
        if(ep->d_type==DT_DIR)
        {
            //当前目录长度
            dirlen=strlen(dirpath)+1;
            //备份
            dirname=(char *)malloc(dirlen);
            memset(dirname,0,dirlen);
            memcpy(dirname,dirpath,dirlen);
            
            strcat(dirpath,"/");
            strcat(dirpath,ep->d_name);
            dirtree(dirpath,level+1);        //递归实现树效果
            //恢复之前的目录名
            memcpy(dirpath,dirname,dirlen);
            free(dirname);            
            dirname = NULL;
        }
    }    
    closedir(dp);
}

//递归查找相似文件-查找文件
int sc_file(struct copypath *pp,char *filename)
{
    DIR *dirp=opendir(pp->oldpath);
    if(dirp==NULL)
    {
        perror("失败:\n");
        return -1;
    }
    struct dirent *p;
    while((p=readdir(dirp))!=NULL)
    {    
        if(p->d_type==DT_REG)        //普通文件
        {
            if(strstr(p->d_name,filename)!=NULL)    //文件类型
            {
                struct copypath *mypath=malloc(sizeof(struct copypath));
                sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
                printf("已找到文件路径:%s\n",mypath->oldpath);
                free(mypath);
            }            
        }
        if(p->d_type==DT_DIR)        //文件夹
        {    
            if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
            {    
                if(strstr(p->d_name,filename)!=NULL)    //文件类型
                {
                    struct copypath *mypath1=malloc(sizeof(struct copypath));
                    sprintf(mypath1->oldpath,"%s/%s",pp->oldpath,p->d_name);
                    printf("已找到文件路径:%s\n",mypath1->oldpath);
                    free(mypath1);
                }
                struct copypath *mydirpath=malloc(sizeof(struct copypath));
                sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
                sc_file(mydirpath,filename);
            }
        }
    }
    closedir(dirp);
    return 1;    
}
//删除--文件\文件夹
int alldet(struct copypath *pp)
{
    DIR *dirp=opendir(pp->oldpath);
    struct dirent *p;
    while((p=readdir(dirp))!=NULL)
    {    
        if(p->d_type==DT_REG)        //普通文件
        {            
            struct copypath *mypath=malloc(sizeof(struct copypath));
            sprintf(mypath->oldpath,"%s/%s",pp->oldpath,p->d_name);
            remove(mypath->oldpath);            
        }
        if(p->d_type==DT_DIR)        //文件夹
        {    
            if(strcmp(p->d_name,".")!=0 && strcmp(p->d_name,"..")!=0)
            {            
                struct copypath *mydirpath=malloc(sizeof(struct copypath));
                sprintf(mydirpath->oldpath,"%s/%s",pp->oldpath,p->d_name);
                alldet(mydirpath);
                rmdir(mydirpath->oldpath);
            }
        }
    }
    closedir(dirp);
    rmdir((pp->oldpath));
    return 1;    
}
/***************************************************************************/

/***************************************************************************/
//                                简化主程序
/***************************************************************************/
int simcopy_all(struct threadpool *mypool)    //简化主程序--复制全部
{    
    tm=s=cs=0;
    struct copypath paths;        //新旧路径结构体
    printf("请输入源文件\n");
    scanf("%s",paths.oldpath);
    printf("请输入目标文件\n");
    scanf("%s",paths.newpath);
    mycopyname(&paths);
    sprintf(paths.newpath,"%s/%s",paths.newpath,paths.target);
    mkdir(paths.newpath,0777);
    size_sum(&paths);        //计算字节数
    usleep(20);
    printf("总字节数:%ld\n",s);
    add_task(my_time,NULL,mypool);
    add_task(pro_bar,NULL,mypool);
    myreaddir(&paths,mypool);
}
void simcopy(struct threadpool *mypool)        //简化主程序--按文件类型复制
{
    tm=s=cs=0;
    char ftype[6];            //文件类型变量
    struct copypath paths;        
    printf("请输入源文件\n");
    scanf("%s",paths.oldpath);
    printf("请输入目标文件\n");
    scanf("%s",paths.newpath);
    mycopyname(&paths);
    sprintf(paths.newpath,"%s/%s",paths.newpath,paths.target);
    mkdir(paths.newpath,0777);
    printf("请输入要复制的文件类型,如.txt等\n");    
    scanf("%s",ftype);
    ftypesize_sum(&paths,ftype);        
    printf("总字节数:%ld\n",s);
    usleep(20);
    add_task(my_time,NULL,mypool);
    add_task(pro_bar,NULL,mypool);
    myftyper(&paths,mypool,ftype);
}
void simtree()                                //简化主程序--文件树
{
    char direntName[256];
    struct copypath paths;
    printf("请输入源文件\n");
    scanf("%s",paths.oldpath);
    memset(direntName, 0, sizeof(direntName));
    strcat(direntName, paths.oldpath);
    printf("%s\n",paths.oldpath);
    dirtree(direntName, 0);
}
void myscfile()                                //简化主程序--查找
{    
    char fname[256];
    struct copypath paths;
    printf("请输入查找文件夹名\n");
    scanf("%s",paths.oldpath);
    printf("请输入要查找的文件名\n");
    scanf("%s",fname);
    sc_file(&paths,fname);
    usleep(10);
}
void mydel()                                //简化主程序--删除
{
    tm=s=cs=0;
    char delfile[100];
    struct copypath paths;
    printf("请输入要删除的文件夹\n");
    scanf("%s",paths.oldpath);
    size_sum(&paths);        //计算字节数
    printf("size is: %ld\n",s);
    alldet(&paths);
    usleep(10);
}
void endshow()                                //简化主程序--结束
{
    printf("请输入          \n");
    printf("    1--继续     \n");
    printf("    2--退出     \n");
    scanf("%d",&flag);
}
/***************************************************************************/
//销毁线程池
int pool_destroy(struct threadpool *pool)
{
    int i;
    //改变标志位,让线程退出死循环
    pool->threadflag=false;
    //唤醒所有线程
    pthread_cond_broadcast(&(pool->threadcond));
    //回收所有线程
    for(i=0;ithreadnum;i++)
    {
        pthread_join(pool->threadid[i],NULL);
        //printf("%ld线程已被回收\n",pool->threadid[i]);
    }
    return 0;
}

int main()
{         
    struct copypath paths;
    while(1)
    {
        flag=0;
        system("clear");                
        myhead=task_init();            //初始化任务链表的表头        
        struct threadpool *mypool=thread_init(10);        //创建并初始化线程池
        int ret=showdow();    
        switch(ret)
        {
            case 1:                        //拷贝全部
                simcopy_all(mypool);                
                pool_destroy(mypool);    //线程池的销毁
                printf("拷贝花费:%d seconds\n",tm);
                break;
            case 2:                        //拷贝部分
                simcopy(mypool);
                pool_destroy(mypool);
                printf("拷贝花费:%d seconds\n",tm);
                break;
            case 3:                        //显示文件树                
                simtree();
                break;
            case 4:                        //查找某个文件--显示相似的文件
                myscfile();
                break;
            case 5:                        //删除某个文件夹
                mydel();                
                printf("delete done\n");
                break;
            default:
                break;
        }
        endshow();        
        if(flag==1)
            continue;
        else if(flag==2)
            break;
    }
    system("clear");
    usleep(20);
    return 0;
}

 码源:

http://pan-yz.chaoxing.com/share/info/b54be58ad063e1e9

有什么建议,欢迎联系。邮箱:2460576606@qq.com