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

基于linux与线程池实现文件管理,第1张

概述 基于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<level;i++)        {            printf("|");            printf("     ");        }        printf("|--- ");        printf("
总结

以上是内存溢出为你收集整理的基于linux与线程池实现文件管理全部内容,希望文章能够帮你解决基于linux与线程池实现文件管理所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/1013648.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存