`
faylai
  • 浏览: 78218 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

纯异步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文件夹(目录)复制功能

    总结来说,纯异步的Node.js文件夹复制涉及到异步读取目录、递归遍历子目录、异步创建目标目录、异步复制文件以及可能的并发控制。这个过程可以通过`fs`模块的异步方法和`async`库的辅助工具来高效实现。

    NodeJS 文件夹拷贝以及删除功能

    NodeJS是一种基于Chrome V8引擎的...以上是根据文章内容解析的关于NodeJS文件夹拷贝及删除功能的知识点。NodeJS的fs模块在处理文件和文件夹操作方面提供了强大而灵活的API,使得开发者可以方便地进行各种文件系统操作。

    Nodejs 复制文件/文件夹的方法

    这行代码创建了一个子进程来执行shell命令,其中cp是Linux下的复制命令,'-r'参数表示递归复制整个文件夹,'source'和'destination'分别是源文件或文件夹和目标文件夹的路径。 在使用child_process.spawn执行命令时...

    Node.JS 循环递归复制文件夹目录及其子文件夹下的所有文件

    在复制目录及其子目录时,首先需要读取源目录中的所有文件和子目录,这可以通过fs.readdir函数完成。一旦获取到文件列表,对于每个文件或子目录,我们需要使用fs.stat来判断它是一个文件还是目录。如果是一个目录,...

    Nodejs实现多文件夹文件同步

    在示例中,`path`对象包含两个文件夹路径,并且在路径中添加了子目录名来访问特定的子目录。 4. **数组操作**:`for...in`循环用来遍历数组,`indexOf`方法用于检查一个元素是否存在于数组中。 5. **函数定义与...

    nodejs 游戏服务端框架 pomelo_免编译版

    (3) 将解压后的文件夹复制到你的项目目录下,确保路径正确。 (4) 在项目中引入Pomelo,配置相关路径,例如在`app.js`中设置`app.set('root', __dirname);`。 (5) 初始化并启动Pomelo服务,如`app.start();`。 4. ...

    nodejs fs 命令相关文件操作

    nodejs 操作文件以及文件夹。 /** * @description: 同步读取 * @param {string} 文件地址 */ readFileSync(src) /** * @description: 异步读取 * @param {string} 文件地址 * @param {Function} 回调函数 */...

    Node.js-cpy-复制文件的包

    标题 "Node.js-cpy-复制文件的包" 指的是一个用于Node.js环境下的工具包,名为`cpy`,它的主要功能是便捷地复制文件或文件夹。这个包简化了在开发过程中需要批量或者精确复制文件的任务,使得开发者可以更高效地管理...

    SaveServer:一个nodejs服务器,可让您每天备份文件

    4. **自动化流程**:为了实现自动化,SaveServer可能包含了一个工作流管理系统,它会根据预设的规则(如备份源、目标目录、备份时间等)自动执行备份过程,无需人工干预。 5. **版本控制**:为了确保文件的历史版本...

    利用node.js实现自动生成前端项目组件的方法详解

    3. **创建文件夹**:使用`fs.mkdir()`异步创建文件夹。创建成功后,更新路径以继续后续操作。 4. **读取模板内容**:读取预先定义好的模板文件,如`index.js`和`cptTemp.js`,以便在新组件文件中填充内容。 5. **...

    node文件批量重命名的方法示例

    2. 判读存放目录是否存在,不存在时新建目录 3. 复制文件 4. 判断复制内容是否为文件 5. 创建读取流 6. 创建写入流 7. 链接管道,写入文件内容 结论 Node 文件批量重命名可以简化文件管理和组织的工作,提高工作...

    hyht-web-basic-v1脚手架的使用详情说明.docx

    (2)修改 Element UI 样式时,避免直接复制和修改 Element 的样式类,以免影响其他页面。应在当前页面内进行修改。 5. **Element 主题**: Element UI 提供了自定义主题的功能。你可以访问 `...

    BasicUtils:基本实用程序机器人

    在使用过程中,根据提供的`BasicUtils-main`这个文件夹名,我们可以推断这是项目的主目录。在该目录下,你可能找到源代码文件(如`.js`或`.ts`),配置文件(如`package.json`),以及可能的测试文件和示例代码。`...

    组狂

    最后,提到的压缩包子文件"Groupomania-main"可能代表了项目的主文件夹或源代码目录。在开发环境中,项目经常被打包成ZIP文件进行分发,这样可以方便地下载和解压到本地进行工作。"main"通常指代项目的主要或核心...

Global site tag (gtag.js) - Google Analytics