• linux 实现cp命令递归复制


      1 #include<func.h>
      2 
      3 #define LENGTH 4096
      4 
      5 int DFS_copy(char* path1, char* path2);  //递归复制
      6 
      7 int main(int argc, char* argv[]) {
      8     ARGS_CHECK(argc, 3); //检查参数是否错误
      9 
     10     struct stat statbuf;
     11     stat(argv[1], &statbuf);
     12     if (S_ISDIR(statbuf.st_mode)) { //若参数1是目录,直接进行递归
     13         DFS_copy(argv[1], argv[2]);
     14 
     15     }
     16     else { //否则参数1就是普通文件
     17         stat(argv[2], &statbuf);
     18         if (S_ISDIR(statbuf.st_mode)) { //若参数2是目录
     19             char newpath1[1024] = { 0 };
     20             char newpath2[1024] = { 0 };
     21             sprintf(newpath1, "%s", argv[1]);//重建待复制的源文件的地址
     22             sprintf(newpath2, "%s%s%s", argv[2], "/", argv[1]);//重建目的文件的地址
     23 
     24             int fdr = open(newpath1, O_RDONLY); //只读方式打开源文件
     25             ERROR_CHECK(fdr, -1, "open fdr");
     26             int fdw = open(newpath2, O_WRONLY | O_CREAT | O_TRUNC, 0666);//只写方式打开目的文件,若不存在就创建,给予权限0666
     27             ERROR_CHECK(fdw, -1, "open fdw");
     28             char buf[4096] = { 0 }; //数据缓存
     29             while (1) {
     30                 memset(buf, 0, sizeof(buf)); //每次清空内容
     31                 int ret = read(fdr, buf, sizeof(buf)); //读内容,返回成功读到的字节数
     32                 if (ret == 0) {
     33                     break;
     34                 }
     35                 write(fdw, buf, ret); //写入到目的文件
     36             }
     37             close(fdr); //关闭文件
     38             close(fdw);
     39         }
     40         else { //若参数2是普通文件,则就是两个普通文件的复制
     41             int fdr = open(argv[1], O_RDONLY); //只读方式打开源文件
     42             ERROR_CHECK(fdr, -1, "open fdr");
     43             int fdw = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666);//只写方式打开目的文件,若不存在就创建,给予权限0666
     44             ERROR_CHECK(fdw, -1, "open fdw");
     45             char buf[4096] = { 0 }; //数据缓存
     46             while (1) {
     47                 memset(buf, 0, sizeof(buf)); //每次清空内容
     48                 int ret = read(fdr, buf, sizeof(buf)); //读内容,返回成功读到的字节数
     49                 if (ret == 0) {
     50                     break;
     51                 }
     52                 write(fdw, buf, ret); //写入到目的文件
     53             }
     54             close(fdr); //关闭文件
     55             close(fdw);
     56         }
     57 
     58     }
     59 
     60     return 0;
     61 }
     62 
     63 int DFS_copy(char* path1, char* path2) {
     64     DIR* pdir1 = opendir(path1); //打开源目录流
     65     ERROR_CHECK(pdir1, NULL, "opendir1"); //检查返回值是否出错
     66     if (NULL == opendir(path2)) { //打开目的文件的目录流,若不是目录就创建文件夹
     67         int ret = mkdir(path2, 0777); //创建目的文件夹
     68         ERROR_CHECK(ret, -1, "mkdir");
     69     }
     70     DIR* pdir2 = opendir(path2); //打开目的文件夹的目录流
     71     ERROR_CHECK(pdir2, NULL, "opendir2"); //检查返回值是否出错
     72     struct dirent* pdirent; //存储目录项信息
     73     while ((pdirent = readdir(pdir1)) != NULL) {  //遍历所有目录项
     74         //过滤.和..目录,不然复制的时候会死循环
     75         if (strcmp(pdirent->d_name, ".") == 0 || strcmp(pdirent->d_name, "..") == 0) {
     76             continue;
     77         }
     78 
     79         char newpath1[1024] = { 0 };
     80         char newpath2[1024] = { 0 };
     81         sprintf(newpath1, "%s%s%s", path1, "/", pdirent->d_name);//重建待复制的源文件的地址
     82         sprintf(newpath2, "%s%s%s", path2, "/", pdirent->d_name);//重建目的文件的地址
     83         if (pdirent->d_type == DT_DIR) { //判断当前目录项是否是个目录
     84             DFS_copy(newpath1, newpath2); //是目录就进行递归复制
     85         }
     86         else { //不是目录就直接复制
     87         //------------------read/write方式复制文件------------------
     88             // int fdr = open(newpath1, O_RDONLY); //只读方式打开源文件
     89             // ERROR_CHECK(fdr, -1, "open fdr");
     90             // int fdw = open(newpath2, O_WRONLY | O_CREAT | O_TRUNC, 0666);//只写方式打开目的文件,若不存在就创建,给予权限0666
     91             // ERROR_CHECK(fdw, -1, "open fdw");
     92             // char buf[4096] = { 0 }; //数据缓存
     93             // while (1) {
     94             //     memset(buf, 0, sizeof(buf)); //每次清空内容
     95             //     int ret = read(fdr, buf, sizeof(buf)); //读内容,返回成功读到的字节数
     96             //     if (ret == 0) {
     97             //         break;
     98             //     }
     99             //     write(fdw, buf, ret); //写入到目的文件
    100             // }
    101             // close(fdr); //关闭文件
    102             // close(fdw);
    103         //--------------------------------------------------------
    104         //------------------mmap方式复制文件-----------------------
    105             int fdr = open(newpath1, O_RDONLY);
    106             ERROR_CHECK(fdr, -1, "open fdr");
    107             int fdw = open(newpath2, O_RDWR | O_CREAT | O_TRUNC, 0666);
    108             ERROR_CHECK(fdw, -1, "open fdw");
    109 
    110             struct stat statbuf;
    111             fstat(fdr, &statbuf); //和stat函数一样,只是参数变为文件描述符
    112             ftruncate(fdw, statbuf.st_size);
    113             off_t fsize = 0;
    114             int cp_size;
    115             while (fsize < statbuf.st_size) {
    116                 if (statbuf.st_size - fsize >= LENGTH) {
    117                     cp_size = LENGTH;
    118                 }
    119                 else {
    120                     cp_size = statbuf.st_size - fsize;
    121                 }
    122 
    123                 char* src = (char*)mmap(NULL, cp_size, PROT_READ, MAP_SHARED, fdr, fsize);
    124                 ERROR_CHECK(src, MAP_FAILED, "mmap");
    125 
    126                 char* dest = (char*)mmap(NULL, cp_size, PROT_WRITE | PROT_READ, MAP_SHARED, fdw, fsize);
    127                 ERROR_CHECK(dest, MAP_FAILED, "mmap");
    128 
    129                 memcpy(dest, src, cp_size);
    130                 // for(int i = 0; i < cp_size; i++){  //另一种转移数据的方式
    131                 //     dest[i] = src[i];
    132                 // }
    133                 munmap(src, cp_size);
    134                 munmap(dest, cp_size);
    135                 fsize += cp_size;
    136             }
    137 
    138             //--------------------------------------------------------
    139         }
    140     }
    141     closedir(pdir1); //关闭目录流
    142     closedir(pdir2);
    143     return 0;
    144 }
  • 相关阅读:
    讲解开源项目:一步步跑起来个 Java 前后端分离的人力资源管理系统
    HelloDjango 第 12 篇:解锁博客侧栏,GoGoGo!
    HelloDjango 第 11 篇:自动生成文章摘要
    Python 命令行之旅:深入 argparse(二)
    MongoDB 复制机制
    GridView自定义分页
    接口分离原则
    依赖倒置原则
    访问 IIS 元数据库失败 的解决方法
    开放封闭原则
  • 原文地址:https://www.cnblogs.com/zq8421/p/16274222.html
Copyright © 2020-2023  润新知