在linux平台上运行,分享给大家。
#include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <errno.h> #include <string.h> #include <dirent.h> void cp_file(const char *src,const char *dst,mode_t mode); void cp_dir(const char *src,const char *dst); int main(int argc,char *argv[]) { if(argc != 3) //判断输入的参数个数 { printf("usage:%s fp_src fp_dst\n",argv[1] ); exit(EXIT_FAILURE); } struct stat stat_src; if(stat(argv[1],&stat_src) == -1) //判断源文件的属性 { perror("stat_src"); exit(EXIT_FAILURE); } if(S_ISREG(stat_src.st_mode)) //如果源文件是文件类型 { struct stat stat_dst; if(stat(argv[2],&stat_dst) == -1) //判断目标文件属性 { if(errno == ENOENT) //如果判断目标文件失败的原因是因为目标文件不存在 cp_file(argv[1],argv[2],stat_src.st_mode); //创建目标文件,执行文件拷贝 else { perror("file:stat_dst"); exit(EXIT_FAILURE); } } if(S_ISREG(stat_dst.st_mode)) //如果目标文件是文件属性,说明目标文件已经存在 { printf("The file is exist,do you want to overwrite it?(y/n)\n"); char c; c = getchar(); if(c == 'y' || c == 'Y') { unlink(argv[2]); cp_file(argv[1],argv[2],stat_src.st_mode); } else if(c == 'n' || c == 'N') { printf("The dst file do not overwrite!\n"); return 0; } else { printf("Enter error!\n"); exit(EXIT_FAILURE); } } if(S_ISDIR(stat_dst.st_mode)) //如果目标文件是文件夹属性 { char *ptr = malloc(strlen(argv[2]) + 1 + strlen(argv[1]) + 1); //创建一个目标路径,将源文件拷贝到目标文件夹下 sprintf(ptr,"%s/%s\0",argv[2],argv[1]); cp_file(argv[1],ptr,stat_src.st_mode); free(ptr); } } else if(S_ISDIR(stat_src.st_mode)) //源文件是文件夹属性 { struct stat stat_dst; if(stat(argv[2],&stat_dst) == -1) { if(errno == ENOENT) //目标文件属性判断失败是因为目标文件不存在 { if(mkdir(argv[2],stat_src.st_mode) == -1) //创建目标文件夹,权限与源文件权限相同 { perror("mkdir stat_dst"); exit(EXIT_FAILURE); } cp_dir(argv[1],argv[2]); //执行文件夹到文件夹的拷贝 } else //目标文件属性判断失败是因为其他原因,则退出程序 { perror("dir:stat_dst"); exit(EXIT_FAILURE); } } if(S_ISREG(stat_dst.st_mode)) //目标文件是文件属性 { printf("Can not copy a file to a directory!\n"); exit(EXIT_FAILURE); } if(S_ISDIR(stat_dst.st_mode)) //目标文件是已经存在的文件夹属性 { char *ptr = malloc(strlen(argv[1]) + 1 +strlen(argv[2]) + 1); //创建拷贝路径,将源文件拷贝到目标文件夹内部 sprintf(ptr,"%s/%s\0",argv[2],argv[1]); printf("ptr = %s",ptr); if(mkdir(ptr,stat_src.st_mode) == -1) //在目标文件内部创建新的文件夹,即与源文件相同名称和权限的文件夹 { perror("mkdir ptr"); exit(EXIT_FAILURE); } cp_dir(argv[1],ptr); free(ptr); } } return 0; } void cp_file(const char *src,const char *dst,mode_t mode) //文件到文件的拷贝 { FILE *fp_src = NULL; FILE *fp_dst = NULL; if((fp_src = fopen(src,"r")) == NULL) { perror("fopen src"); exit(EXIT_FAILURE); } if((fp_dst = fopen(dst,"w")) == NULL) { perror("fopen dst"); exit(EXIT_FAILURE); } char buf[128]; int ret = 0; while(1) //循环读取源文件信息 { memset(buf,'\0',128); ret = fread(buf,1,127,fp_src); fwrite(buf,1,ret,fp_dst); if(ret <= 0) break; } fclose(fp_src); fclose(fp_dst); } void cp_dir(const char *src,const char *dst) //文件夹到文件夹的拷贝 { DIR *fp_src = NULL; if((fp_src = opendir(src)) == NULL) { perror("opendir fp_src"); exit(EXIT_FAILURE); } struct dirent *fp = NULL; while((fp = readdir(fp_src)) != NULL) { if(strcmp(fp->d_name,".") == 0 || strcmp(fp->d_name,"..") == 0) continue; char *name_src = malloc(strlen(src) + 1 + strlen(fp->d_name) + 1); //用一个指针指向源文件夹内部的文件的路径 sprintf(name_src,"%s/%s\0",src,fp->d_name); char *name_dst = malloc(strlen(dst) + 1 + strlen(fp->d_name) + 1); sprintf(name_dst,"%s/%s\0",dst,fp->d_name); struct stat stat_src; if(stat(name_src,&stat_src) == -1) { perror("name_src"); exit(EXIT_FAILURE); } if(S_ISREG(stat_src.st_mode)) { cp_file(name_src,name_dst,stat_src.st_mode); free(name_src); free(name_dst); } if(S_ISDIR(stat_src.st_mode)) { if(mkdir(name_dst,stat_src.st_mode) == -1) { perror("mkdir name_dst"); exit(EXIT_FAILURE); } cp_dir(name_src,name_dst); free(name_src); free(name_dst); } } }