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

叁歲伎倆 2022-12-29 06:19 294阅读 0赞

来源于高级程序设计 杨宗德(第三版)

在linux平台上运行,分享给大家。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/stat.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <dirent.h>
  7. void cp_file(const char *src,const char *dst,mode_t mode);
  8. void cp_dir(const char *src,const char *dst);
  9. int main(int argc,char *argv[])
  10. {
  11. if(argc != 3) //判断输入的参数个数
  12. {
  13. printf("usage:%s fp_src fp_dst\n",argv[1] );
  14. exit(EXIT_FAILURE);
  15. }
  16. struct stat stat_src;
  17. if(stat(argv[1],&stat_src) == -1) //判断源文件的属性
  18. {
  19. perror("stat_src");
  20. exit(EXIT_FAILURE);
  21. }
  22. if(S_ISREG(stat_src.st_mode)) //如果源文件是文件类型
  23. {
  24. struct stat stat_dst;
  25. if(stat(argv[2],&stat_dst) == -1) //判断目标文件属性
  26. {
  27. if(errno == ENOENT) //如果判断目标文件失败的原因是因为目标文件不存在
  28. cp_file(argv[1],argv[2],stat_src.st_mode); //创建目标文件,执行文件拷贝
  29. else
  30. {
  31. perror("file:stat_dst");
  32. exit(EXIT_FAILURE);
  33. }
  34. }
  35. if(S_ISREG(stat_dst.st_mode)) //如果目标文件是文件属性,说明目标文件已经存在
  36. {
  37. printf("The file is exist,do you want to overwrite it?(y/n)\n");
  38. char c;
  39. c = getchar();
  40. if(c == 'y' || c == 'Y')
  41. {
  42. unlink(argv[2]);
  43. cp_file(argv[1],argv[2],stat_src.st_mode);
  44. }
  45. else if(c == 'n' || c == 'N')
  46. {
  47. printf("The dst file do not overwrite!\n");
  48. return 0;
  49. }
  50. else
  51. {
  52. printf("Enter error!\n");
  53. exit(EXIT_FAILURE);
  54. }
  55. }
  56. if(S_ISDIR(stat_dst.st_mode)) //如果目标文件是文件夹属性
  57. {
  58. char *ptr = malloc(strlen(argv[2]) + 1 + strlen(argv[1]) + 1); //创建一个目标路径,将源文件拷贝到目标文件夹下
  59. sprintf(ptr,"%s/%s\0",argv[2],argv[1]);
  60. cp_file(argv[1],ptr,stat_src.st_mode);
  61. free(ptr);
  62. }
  63. }
  64. else if(S_ISDIR(stat_src.st_mode)) //源文件是文件夹属性
  65. {
  66. struct stat stat_dst;
  67. if(stat(argv[2],&stat_dst) == -1)
  68. {
  69. if(errno == ENOENT) //目标文件属性判断失败是因为目标文件不存在
  70. {
  71. if(mkdir(argv[2],stat_src.st_mode) == -1) //创建目标文件夹,权限与源文件权限相同
  72. {
  73. perror("mkdir stat_dst");
  74. exit(EXIT_FAILURE);
  75. }
  76. cp_dir(argv[1],argv[2]); //执行文件夹到文件夹的拷贝
  77. }
  78. else //目标文件属性判断失败是因为其他原因,则退出程序
  79. {
  80. perror("dir:stat_dst");
  81. exit(EXIT_FAILURE);
  82. }
  83. }
  84. if(S_ISREG(stat_dst.st_mode)) //目标文件是文件属性
  85. {
  86. printf("Can not copy a file to a directory!\n");
  87. exit(EXIT_FAILURE);
  88. }
  89. if(S_ISDIR(stat_dst.st_mode)) //目标文件是已经存在的文件夹属性
  90. {
  91. char *ptr = malloc(strlen(argv[1]) + 1 +strlen(argv[2]) + 1); //创建拷贝路径,将源文件拷贝到目标文件夹内部
  92. sprintf(ptr,"%s/%s\0",argv[2],argv[1]);
  93. printf("ptr = %s",ptr);
  94. if(mkdir(ptr,stat_src.st_mode) == -1) //在目标文件内部创建新的文件夹,即与源文件相同名称和权限的文件夹
  95. {
  96. perror("mkdir ptr");
  97. exit(EXIT_FAILURE);
  98. }
  99. cp_dir(argv[1],ptr);
  100. free(ptr);
  101. }
  102. }
  103. return 0;
  104. }
  105. void cp_file(const char *src,const char *dst,mode_t mode) //文件到文件的拷贝
  106. {
  107. FILE *fp_src = NULL;
  108. FILE *fp_dst = NULL;
  109. if((fp_src = fopen(src,"r")) == NULL)
  110. {
  111. perror("fopen src");
  112. exit(EXIT_FAILURE);
  113. }
  114. if((fp_dst = fopen(dst,"w")) == NULL)
  115. {
  116. perror("fopen dst");
  117. exit(EXIT_FAILURE);
  118. }
  119. char buf[128];
  120. int ret = 0;
  121. while(1) //循环读取源文件信息
  122. {
  123. memset(buf,'\0',128);
  124. ret = fread(buf,1,127,fp_src);
  125. fwrite(buf,1,ret,fp_dst);
  126. if(ret <= 0)
  127. break;
  128. }
  129. fclose(fp_src);
  130. fclose(fp_dst);
  131. }
  132. void cp_dir(const char *src,const char *dst) //文件夹到文件夹的拷贝
  133. {
  134. DIR *fp_src = NULL;
  135. if((fp_src = opendir(src)) == NULL)
  136. {
  137. perror("opendir fp_src");
  138. exit(EXIT_FAILURE);
  139. }
  140. struct dirent *fp = NULL;
  141. while((fp = readdir(fp_src)) != NULL)
  142. {
  143. if(strcmp(fp->d_name,".") == 0 || strcmp(fp->d_name,"..") == 0)
  144. continue;
  145. char *name_src = malloc(strlen(src) + 1 + strlen(fp->d_name) + 1); //用一个指针指向源文件夹内部的文件的路径
  146. sprintf(name_src,"%s/%s\0",src,fp->d_name);
  147. char *name_dst = malloc(strlen(dst) + 1 + strlen(fp->d_name) + 1);
  148. sprintf(name_dst,"%s/%s\0",dst,fp->d_name);
  149. struct stat stat_src;
  150. if(stat(name_src,&stat_src) == -1)
  151. {
  152. perror("name_src");
  153. exit(EXIT_FAILURE);
  154. }
  155. if(S_ISREG(stat_src.st_mode))
  156. {
  157. cp_file(name_src,name_dst,stat_src.st_mode);
  158. free(name_src);
  159. free(name_dst);
  160. }
  161. if(S_ISDIR(stat_src.st_mode))
  162. {
  163. if(mkdir(name_dst,stat_src.st_mode) == -1)
  164. {
  165. perror("mkdir name_dst");
  166. exit(EXIT_FAILURE);
  167. }
  168. cp_dir(name_src,name_dst);
  169. free(name_src);
  170. free(name_dst);
  171. }
  172. }
  173. }

发表评论

表情:
评论列表 (有 0 条评论,294人围观)

还没有评论,来说两句吧...

相关阅读