纯异步nodejs文件夹(目录)复制功能


Posted in NodeJs onSeptember 03, 2019

node.js 复制文件夹

思路:

1、callback 驱动

2、递归所有需要复制文件

3、在一定阀值下并发复制文件

var async = require("async"); 
var fs = require("fs"); 
var path = require("path"); 
// cursively make dir  
function mkdirs(p, mode, f, made) { 
  if (typeof mode === 'function' || mode === undefined) { 
    f = mode; 
    mode = 0777 & (~process.umask()); 
  } 
  if (!made) 
    made = null; 
  var cb = f || function () {}; 
  if (typeof mode === 'string') 
    mode = parseInt(mode, 8); 
  p = path.resolve(p); 
  fs.mkdir(p, mode, function (er) { 
    if (!er) { 
      made = made || p; 
      return cb(null, made); 
    } 
    switch (er.code) { 
    case 'ENOENT': 
      mkdirs(path.dirname(p), mode, function (er, made) { 
        if (er) { 
          cb(er, made); 
        } else { 
          mkdirs(p, mode, cb, made); 
        } 
      }); 
      break; 
      // In the case of any other error, just see if there's a dir 
      // there already. If so, then hooray! If not, then something 
      // is borked. 
    default: 
      fs.stat(p, function (er2, stat) { 
        // if the stat fails, then that's super weird. 
        // let the original error be the failure reason. 
        if (er2 || !stat.isDirectory()) { 
          cb(er, made); 
        } else { 
          cb(null, made) 
        }; 
      }); 
      break; 
    } 
  }); 
} 
// single file copy 
function copyFile(file, toDir, cb) { 
  async.waterfall([ 
      function (callback) { 
        fs.exists(toDir, function (exists) { 
          if (exists) { 
            callback(null, false); 
          } else { 
            callback(null, true); 
          } 
        }); 
      }, function (need, callback) { 
        if (need) { 
          mkdirs(path.dirname(toDir), callback); 
        } else { 
          callback(null, true); 
        } 
      }, function (p, callback) { 
        var reads = fs.createReadStream(file); 
        var writes = fs.createWriteStream(path.join(path.dirname(toDir), path.basename(file))); 
        reads.pipe(writes); 
        //don't forget close the when all the data are read 
        reads.on("end", function () { 
          writes.end(); 
          callback(null); 
        }); 
        reads.on("error", function (err) { 
          console.log("error occur in reads"); 
          callback(true, err); 
        }); 
      } 
    ], cb); 
} 
// cursively count the files that need to be copied 
function _ccoutTask(from, to, cbw) { 
  async.waterfall([ 
      function (callback) { 
        fs.stat(from, callback); 
      }, 
      function (stats, callback) { 
        if (stats.isFile()) { 
          cbw.addFile(from, to); 
          callback(null, []); 
        } else if (stats.isDirectory()) { 
          fs.readdir(from, callback); 
        } 
      }, 
      function (files, callback) { 
        if (files.length) { 
          for (var i = 0; i < files.length; i++) { 
            _ccoutTask(path.join(from, files[i]), path.join(to, files[i]), cbw.increase()); 
          } 
        } 
        callback(null); 
      } 
    ], cbw); 
} 
// wrap the callback before counting 
function ccoutTask(from, to, cb) { 
  var files = []; 
  var count = 1; 
  function wrapper(err) { 
    count--; 
    if (err || count <= 0) { 
      cb(err, files) 
    } 
  } 
  wrapper.increase = function () { 
    count++; 
    return wrapper; 
  } 
  wrapper.addFile = function (file, dir) { 
    files.push({ 
      file : file, 
      dir : dir 
    }); 
  } 
  _ccoutTask(from, to, wrapper); 
} 
function copyDir(from, to, cb) { 
  if(!cb){ 
   cb=function(){}; 
  } 
  async.waterfall([ 
      function (callback) { 
        fs.exists(from, function (exists) { 
          if (exists) { 
            callback(null, true); 
          } else { 
            console.log(from + " not exists"); 
            callback(true); 
          } 
        }); 
      }, 
      function (exists, callback) { 
        fs.stat(from, callback); 
      }, 
      function (stats, callback) { 
        if (stats.isFile()) { 
          // one file copy 
          copyFile(from, to, function (err) { 
            if (err) { 
              // break the waterfall 
              callback(true); 
            } else { 
              callback(null, []); 
            } 
          }); 
        } else if (stats.isDirectory()) { 
          ccoutTask(from, to, callback); 
        } 
      }, 
      function (files, callback) {   
        // prevent reaching to max file open limit      
        async.mapLimit(files, 10, function (f, cb) { 
          copyFile(f.file, f.dir, cb); 
        }, callback); 
      } 
    ], cb); 
} 
var start = new Date().getTime(); 
copyDir("F:\\gear", "F:\\gear2", function (err) { 
  if (err) { 
    console.log("error ocur"); 
    console.dir(err); 
  } else { 
    console.log("copy ok"); 
    console.log("consume time:" + (new Date().getTime() - start)) 
  } 
});

总结

以上所述是小编给大家介绍的纯异步nodejs文件夹(目录)复制,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

NodeJs 相关文章推荐
Ubuntu中搭建Nodejs开发环境过程分享
Jun 01 NodeJs
ubuntu下安装nodejs以及升级的办法
May 08 NodeJs
nodejs实现bigpipe异步加载页面方案
Jan 26 NodeJs
NodeJs——入门必看攻略
Jun 27 NodeJs
nodejs如何获取时间戳与时间差
Aug 03 NodeJs
详解使用vscode+es6写nodejs服务端调试配置
Sep 21 NodeJs
nodeJs实现基于连接池连接mysql的方法示例
Feb 10 NodeJs
Nodejs模块载入运行原理
Feb 23 NodeJs
nodeJS进程管理器pm2的使用
Jan 09 NodeJs
nodejs和react实现即时通讯简易聊天室功能
Aug 21 NodeJs
Nodejs封装类似express框架的路由实例详解
Jan 05 NodeJs
node快速搭建后台的实现步骤
Feb 18 NodeJs
nodejs文件夹深层复制功能
Sep 03 #NodeJs
Nodejs中使用puppeteer控制浏览器中视频播放功能
Aug 26 #NodeJs
nodejs简单抓包工具使用详解
Aug 23 #NodeJs
nodejs使用node-xlsx生成excel的方法示例
Aug 22 #NodeJs
Nodejs libuv运行原理详解
Aug 21 #NodeJs
nodejs和react实现即时通讯简易聊天室功能
Aug 21 #NodeJs
Nodejs 识别图片类型的方法
Aug 15 #NodeJs
You might like
PHP实现用户认证及管理完全源码
2007/03/11 PHP
php查询mssql出现乱码的解决方法
2014/12/29 PHP
PHP 使用memcached简单示例分享
2015/03/05 PHP
PHP实现批量检测网站是否能够正常打开的方法
2016/08/23 PHP
(currentStyle)javascript为何有时用style得不到已设定的CSS的属性
2007/08/15 Javascript
JQuery异步加载无限下拉框级联功能实现示例
2014/02/19 Javascript
javascript的tab切换原理与效果实现方法
2015/01/10 Javascript
浅谈JavaScript中setInterval和setTimeout的使用问题
2015/08/01 Javascript
理解Javascript的call、apply
2015/12/16 Javascript
微信小程序之购物车功能
2020/09/23 Javascript
讲解vue-router之命名路由和命名视图
2018/05/28 Javascript
详解如何在vscode里面调试js和node.js的方法步骤
2018/12/24 Javascript
NodeJs操作MongoDB教程之分页功能以及常见问题
2019/04/09 NodeJs
vue cli 3.0 搭建项目的图文教程
2019/05/17 Javascript
微信小程序实现弹出菜单动画
2019/06/21 Javascript
javascript/jquery实现点击触发事件的方法分析
2019/11/11 jQuery
[37:22]DOTA2上海特级锦标赛D组资格赛#2 Liquid VS VP第一局
2016/02/28 DOTA
[01:34:42]NAVI vs EG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python实现的一个找零钱的小程序代码分享
2014/08/25 Python
pycharm设置注释颜色的方法
2018/05/23 Python
python的pandas工具包,保存.csv文件时不要表头的实例
2018/06/14 Python
对python当中不在本路径的py文件的引用详解
2018/12/15 Python
tensorflow2.0与tensorflow1.0的性能区别介绍
2020/02/07 Python
django项目中新增app的2种实现方法
2020/04/01 Python
python爬取音频下载的示例代码
2020/10/19 Python
Biblibili视频投稿接口分析并以Python实现自动投稿功能
2021/02/05 Python
Python页面加载的等待方式总结
2021/02/28 Python
阿迪达斯西班牙官方网站:adidas西班牙
2016/07/21 全球购物
计算机专业推荐信范文
2013/11/27 职场文书
社区端午节活动方案
2014/01/28 职场文书
青年教师培训方案
2014/02/06 职场文书
电子商务专业求职信
2014/03/08 职场文书
《每逢佳节倍思亲》教后反思
2014/04/19 职场文书
《棉鞋里的阳光》教学反思
2014/04/24 职场文书
解决python3安装pandas出错的问题
2021/05/20 Python
Redis特殊数据类型Geospatial地理空间
2022/06/01 Redis