分享

linux下递归复制文件及目录

 木芙蓉的图书馆 2011-07-17

#include"filecopy.c"
#include<dirent.h>
#define SIZE 100
/*递归输出文件和目录的名字*/

int distance=0;
char src[SIZE],obj[SIZE],NAME[SIZE];
char *ptr=NAME;
static bool entry(char*path);
static bool walk(char*,bool(*fcn)(char*));
static bool push(char*);
static bool pop(char*);
static char *change(char*);

int main(int argc,char*argv[])
{
NAME[0]='\0';
if(argv[1][0]=='.') push(getcwd(NULL,0));

strcpy(src,NAME);
strcpy(obj,argv[2]);
/*确定源文件的根目录和目标文件的根目录*/
ec_false(entry(argv[1]))
/*从源文件的根目录开始工作*/
return 0;
FIX(return 1;)
}



static bool walk(char*path,bool(*func)(char*)) /*遍历一个目录,对其每个项目使用func函数*/
{
DIR *sp=NULL;
struct dirent *bp;
int fd=-1;
struct stat st;

ec_null(sp=opendir(path))
ec_neg1(fd=open(".",O_RDONLY))/*当前目录为待遍历的目录,先记录,再跳转*/
ec_neg1(chdir(path))

while(errno=0,(bp=readdir(sp))!=NULL){
   if(strcmp(bp->d_name,".")==0||strcmp(bp->d_name,"..")==0) continue;
   else{
      ec_false((*func)(bp->d_name))
}      
}

fchdir(fd);
closedir(sp);
return true;

EC_CLEANUP_BGN
fchdir(fd);
closedir(sp);
return false;
EC_CLEANUP_END
}

static bool entry(char*path)
{
struct stat st;
ec_neg1(lstat(path,&st))
int j;
if((st.st_mode&S_IFMT)==S_IFDIR){
       distance++;    
       for(j=1;j<distance;j++) printf("\t");
       if(path[0]!='.')push(path);
        printf("%s to %s\n",NAME,change(NAME));

        ec_neg1(mkdir(change(NAME),PERM_DIRECTORY))

         ec_false(walk(path,entry))
       if(path[0]!='.')pop(path);
      distance--;
   }
else{
     for(j=1;j<distance;j++) printf("\t");
      push(path);
       printf("%s to %s\n",NAME,change(NAME));
    
      ec_false(filecopy(path,change(NAME)))
     
      pop(path);
}
return true;   
FIX(return false;)
}

static bool push(char*s)
{
char*p;
p=s;
if(*ptr!='/'&&s[0]!='/')*ptr++='/';

while(*p)
   *ptr++=*p++;
   *ptr='\0';
if(ptr-NAME<100)return true;
return false;
}


static bool pop(char*path)
{
int i=strlen(path);
if(*ptr=='/')ptr--;
while(i-->=0) ptr--;
if(ptr!=NAME)*ptr='\0';

if(ptr>NAME)return true;
return false;
}

static char *change(char*overpath) /*将完整的源文件名称转换为完整的目标文件名称*/
{
char *result=(char*)malloc(SIZE*sizeof(char)),*p1,*p2;
strcpy(result,obj);

p1=overpath;
p2=src;
while(*p2++)p1++;

strcat(result,p1);
return result;
}


简单介绍一下各个函数:
main函数:处理命令行变元,产生源文件的根目录和目标文件的根目录;特别的,假如源文件的根目录以“.”表示的话,要用getcwd(获取当前路径)的返回值来替换。

entry函数(进行核心工作):
对一个文件进行如下工作:
(1)是一个目录,那么将名称入栈,调用walk函数遍历之,并向屏幕输出待复制的源目录和目标目录,遍历完以后名称要出栈;如果可能,复制目录
   (2)是一个文件,除了不遍历,其他相同;

walk函数:用func所指向的回调函数(其实就是entry函数)遍历一个目录


注意:entry函数和walk函数互相调用,构成递归

push函数和pop函数:将给定的文件/目录名字出栈或者入栈,构成一个完整的路径名

change函数:根据给点的源文件根目录和目标文件根目录,将一个完整的源路径名称转换为一个完整的目标文件名称。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多