Linux下实现文件夹复制

直接代码:
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h>
#include <utime.h>
#include <dirent.h> 
#include <sys/stat.h> 
#include <fcntl.h> 

#define N 4096 
int cp(char dir_s[],char dir_d[]) 
    int i,j,n; 
    DIR *dp; 
    char stmp[N],dtmp[N]; 
    struct dirent *dir_list;  //获得目录下文件列表信息
    struct stat file_status;  //获取文件信息
    if ( (dp = opendir(dir_s)) == NULL){ 
        printf("cp: cannot access %s: No such file or directory\n",dir_s); 
        return 1; 
    }
    n=0; 
    while ( (dir_list = readdir(dp)) != NULL){      
        if(strcmp(dir_list->d_name, ".")==0 || strcmp(dir_list->d_name,"..")==0){
            continue;
        }
        strcpy(stmp,dir_s); 
        strcat(stmp,dir_list->d_name); 
        if (lstat(stmp,&file_status) < 0){  //获取文件(目录)属性
             printf("Cannot open the directory : %s\n",stmp); 
             break; 
        } 
        printf("%s\n",stmp);
        strcpy(dtmp,dir_d); 
        strcat(dtmp,dir_list->d_name);

        if (S_ISDIR(file_status.st_mode)) { 
            copydir(stmp,dtmp);
        } 
        else    if(S_ISLNK(file_status.st_mode)){
            copylink(stmp,dtmp);
        }
        else    {  
            copyfile(stmp,dtmp);
        } 
    } 
    closedir(dp); 
    return 0; 
}

//P210 复制文件
void copyfile(char dir_s[],char dir_d[]){
    int s_file,d_file,j; 
    char buf[N];
    struct stat file_status;
    struct utimbuf file_time;
    
    if(lstat(dir_s,&file_status)<0){
        printf("Can't get file status\n");
        return ;
    }
    s_file=open(dir_s,O_RDWR);
    if (s_file== -1){ 
        printf("open s file error\n"); 
        return ;
    } 
    d_file=creat(dir_d,file_status.st_mode);
    if (d_file == -1) { 
        printf("open d file error\n"); 
        return ; 
    } 
    while((j=read(s_file,buf,1024))>0){  //写入文件内容
        write(d_file,buf,j); 
    } 
    chmod(dir_d,file_status.st_mode);
    file_time.actime = file_status.st_atime; //更改时间
    file_time.modtime = file_status.st_mtime;
    remove()
    utime(dir_d,&file_time);
    close(s_file); 
    close(d_file);
    return ; 
}

//复制link
void copylink(char dir_s[],char dir_d[]){
    char buf[N];
    struct stat file_status;
    struct utimbuf file_time;
    readlink(dir_s,buf,1024);     //读取链接文件本身信息 (P209)
    symlink(buf,dir_d);          //创建符号链接文件
    lstat(dir_s,&file_status);
    struct timespec filetime[2] = {file_status.st_atim,file_status.st_mtim};
    utimensat(AT_FDCWD//当dir_d是绝对路径:忽略
                ,dir_d,filetime,
                AT_SYMLINK_NOFOLLOW);//only itself
}

//复制目录
void copydir(char dir_s[],char dir_d[]){
    struct stat file_status;  //获取文件信息
    struct utimbuf file_time;
    if (dir_s[strlen(dir_s)-1] != '/'){ 
        strcat(dir_s,"/");
    }
    lstat(dir_s,&file_status);
    mkdir(dir_d,file_status.st_mode);      //创建目录
    if (dir_d[strlen(dir_d)-1] != '/'){ 
        strcat(dir_d,"/");
    }
    cp(dir_s,dir_d); 
    file_time.actime  = file_status.st_atime;    //改变时间
    file_time.modtime = file_status.st_mtime;
    utime(dir_d,&file_time);
}

int main(int argc, char *argv[]) 
    char dir_s[N],dir_d[N],temp[N],path[N];
    struct stat file_status;  //获取文件信息
    struct utimbuf file_time;
    char *file_name,*ch;
    DIR *dp;
    if (argc == 3)
        strcpy(dir_d,argv[2]);
        if (dir_d[strlen(dir_d)-1] != '/'){ 
            strcat(dir_d,"/"); 
            strcpy(temp,dir_d); //复制文件路径
        } 
        strcpy(dir_s,argv[1]);
        lstat(dir_s,&file_status);//获取文件相关信息
        if((dp=opendir(dir_d))==NULL){
            mkdir(dir_d,file_status.st_mode);//建立一个目录
        }
        if (S_ISDIR(file_status.st_mode)) {
            if (dir_s[strlen(dir_s)-1] != '/'){ 
                strcat(dir_s,"/");
            }
            printf("commnd cp %s %s \n",dir_s,dir_d);
            cp(dir_s,dir_d);      //参数应为绝对路径 
        } 
        else  {
            file_name = strrchr(dir_s,'/');
            file_name++;
            int i = 0;
            for(ch = dir_s;ch<file_name;ch++){
                path[i++] =*ch;
            }
            printf("%s\n",path);
            strcat(dir_d,file_name);      //改变目标路径
            if(S_ISLNK(file_status.st_mode)){
                copylink(dir_s,dir_d);
            }
            else    {  
                copyfile(dir_s,dir_d);
            }
            lstat(path,&file_status);
        }
        file_time.actime  = file_status.st_atime;    //改变时间
        file_time.modtime = file_status.st_mtime;
        strcpy(dir_d,temp);
        utime(dir_d,&file_time);
    } 
    else { 
        printf("Argument error\n"); 
    }
    return 0; 

猜你喜欢

转载自blog.csdn.net/sufanzhan/article/details/80286011