纯异步nodejs文件夹(目录)复制
思路:
1、callback 驱动
2、递归所有需要复制文件
3、在一定阀值下并发复制文件
4、运行需要安装 async.js npm install async
代码如下:
- 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文件夹(目录)复制的更多相关文章
- 工具:从一个文件夹中复制jar到另一个文件夹中
工具类:从一个文件夹中复制jar到另一个文件夹中 需要的小伙伴可以试一试,很爽哦,有时候真的很需要! 需求:当我们拿到一个maven项目时,而maven项目的jar包都是通过pom.xml文件管理的, ...
- 【转载】ASP.NET工具类:文件夹目录Directory操作工具类
在ASP.NET开发网站的过程中,有时候会涉及到文件夹相关操作,如判断文件夹目录是否存在.删除文件夹目录.创建文件.删除文件.复制文件夹等等.这一批有关文件目录的操作可以通过Directory类.Fi ...
- A1制作文件夹目录
第一步 在文件夹目录下建立bat文件,填写以下内容: dir *.* /B >目录.txt 最后双击bat文件. 第二步 运行后复制目录.txt文件内容到空白excel 使用hyperlink函 ...
- Node.js 文件夹目录结构创建
第一次接触NodeJS的文件系统就被它的异步的响应给搞晕了,后来发现NodeJS判断文件夹是否存在和创建文件夹是还有同步方法的,但是还是想尝试使用异步的方法去实现. 使用的方法:fs.exists(p ...
- Java修炼——文件夹的复制
文件夹的复制用到了俩个流:缓冲流和文件字节流 缓冲流用来加快写入和读取速度. 在这里我简述一下复制文件夹的过程,当然复制文件夹都可以,复制文件更是不在话下 1.首先要明确俩点.要复制的文件夹的位置(源 ...
- linux系统下修改文件夹目录权限
linux系统下修改文件夹目录权限 文件夹权限问题 Linux.Fedora.Ubuntu修改文件.文件夹权限的方法差不多.很多人开始接触Linux时都很头痛Linux的文件权限问题.这里告诉大家如何 ...
- linux下跨服务器文件文件夹的复制
文件的复制:scp –P (端口号) ./authorized_keys berchina@hadoop002:/home/berchina 文件夹的复制:scp -r -P (端口号) /home/ ...
- 【转载】C#递归删除文件夹目录及文件
在C#文件操作过程中,有时候需要删除相应目录,如果文件夹中含有其他文件夹或者文件,也需要一并进行删除,此时可能就需要使用递归来删除文件夹目录以及文件,递归过程中,如果遍历的对象是文件夹,则删除文件夹, ...
- C# -- 使用递归列出文件夹目录及目录下的文件
使用递归列出文件夹目录及目录的下文件 1.使用递归列出文件夹目录及目录下文件,并将文件目录结构在TreeView控件中显示出来. 新建一个WinForm应用程序,放置一个TreeView控件: 代码实 ...
随机推荐
- 如何控制WAP网站上输入框的默认键盘类型
百度上对这样的资料介绍很多,基本上都和这个页面是一个意思 http://www.w3school.com.cn/html5/att_input_type.asp : 语法 <input type ...
- 微信公众平台消息接口开发(31)微信浏览器HTTP_USER_AGENT判断
微信公众平台开发 微信公众平台开发者 微信公众平台开发模式 微信浏览器 HTTP_USER_AGENT作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/archiv ...
- 1.通过模板创建MAP版本项目
1.选择mpa+ef+module-zero 取名字 2.用vs打开项目后,在解决方案上右键 还原nuget包 3.打开程序包管理器控制台,选择以EntityFramework结尾的项目,并执行upd ...
- Unity3d 鼠标的事件GetMouseButtonDown()、GetMouseButton()、GetMouseButtonUp()
当鼠标按键按下时,返回一次true,后面參数0是左键,1是右键,2是中键 if(Input.GetMouseButtonDown(0)) Debug.Log("Pressed left cl ...
- <PC>HP网络共享并创建一个热点问题
郁闷了一年多 你不能使用本地连接的开放热点 网上说的网卡驱动程序,系统设置等.,我们解决不了 原本BIOS节能设置错误 导致在连续主动对自己的有线无线功能被禁用 该LAN\WLAN Switchin ...
- Delphi 接口使用中,对象生命周期管理,如何释放需要注意的问题
网上有篇文章<Delphi接口编程的两大陷阱>,里面提到接口的生存期管理的问题.但该文章里面提到的两个问题,其实都是对 Delphi 不理解导致的. 先说该篇文章中提到的第一个问题为什 ...
- ios7 获取UITablleViewCell
iOS7之前UITablleViewCell中得contentView得superView就是UITableViewCell.但是在iOS7得时候,contentView得superView确实UIT ...
- mariadb 允许远程访问
进入MariaDB服务器,将mysql.user的host字段的值改为%就表示在任何客户端机器上能以root用户登录到mysql服务器,建议在开发时设为%. 1 MariaDB [(none)]> ...
- UWP入门(八)--几个简单的控件
原文:UWP入门(八)--几个简单的控件 每天看几个,要不聊几天我就可以看完啦,加油! 看效果 1. CheckBox <TextBlock Grid.Row="0" Tex ...
- Android UI中英文自动显示问题
最近做了一个项目,其中有个视频和图片需要添加各种水印(日期,地点,经纬度,用户ID,产品ID等)问题,而且水印还要支持中英文自动切换显示.功能设计和实现算是比较顺利.昨天测试部给了一个小Bug,那就是 ...