linux C文件到文件,文件到文件夹,文件夹到文件夹的拷贝

来源:互联网 发布:mac版sai没有压感 编辑:程序博客网 时间:2024/04/28 08:46
来源于高级程序设计 杨宗德(第三版)

在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);}}}


原创粉丝点击