思路:
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)) } });
相关推荐
总结来说,纯异步的Node.js文件夹复制涉及到异步读取目录、递归遍历子目录、异步创建目标目录、异步复制文件以及可能的并发控制。这个过程可以通过`fs`模块的异步方法和`async`库的辅助工具来高效实现。
NodeJS是一种基于Chrome V8引擎的...以上是根据文章内容解析的关于NodeJS文件夹拷贝及删除功能的知识点。NodeJS的fs模块在处理文件和文件夹操作方面提供了强大而灵活的API,使得开发者可以方便地进行各种文件系统操作。
这行代码创建了一个子进程来执行shell命令,其中cp是Linux下的复制命令,'-r'参数表示递归复制整个文件夹,'source'和'destination'分别是源文件或文件夹和目标文件夹的路径。 在使用child_process.spawn执行命令时...
在复制目录及其子目录时,首先需要读取源目录中的所有文件和子目录,这可以通过fs.readdir函数完成。一旦获取到文件列表,对于每个文件或子目录,我们需要使用fs.stat来判断它是一个文件还是目录。如果是一个目录,...
在示例中,`path`对象包含两个文件夹路径,并且在路径中添加了子目录名来访问特定的子目录。 4. **数组操作**:`for...in`循环用来遍历数组,`indexOf`方法用于检查一个元素是否存在于数组中。 5. **函数定义与...
(3) 将解压后的文件夹复制到你的项目目录下,确保路径正确。 (4) 在项目中引入Pomelo,配置相关路径,例如在`app.js`中设置`app.set('root', __dirname);`。 (5) 初始化并启动Pomelo服务,如`app.start();`。 4. ...
nodejs 操作文件以及文件夹。 /** * @description: 同步读取 * @param {string} 文件地址 */ readFileSync(src) /** * @description: 异步读取 * @param {string} 文件地址 * @param {Function} 回调函数 */...
标题 "Node.js-cpy-复制文件的包" 指的是一个用于Node.js环境下的工具包,名为`cpy`,它的主要功能是便捷地复制文件或文件夹。这个包简化了在开发过程中需要批量或者精确复制文件的任务,使得开发者可以更高效地管理...
4. **自动化流程**:为了实现自动化,SaveServer可能包含了一个工作流管理系统,它会根据预设的规则(如备份源、目标目录、备份时间等)自动执行备份过程,无需人工干预。 5. **版本控制**:为了确保文件的历史版本...
3. **创建文件夹**:使用`fs.mkdir()`异步创建文件夹。创建成功后,更新路径以继续后续操作。 4. **读取模板内容**:读取预先定义好的模板文件,如`index.js`和`cptTemp.js`,以便在新组件文件中填充内容。 5. **...
2. 判读存放目录是否存在,不存在时新建目录 3. 复制文件 4. 判断复制内容是否为文件 5. 创建读取流 6. 创建写入流 7. 链接管道,写入文件内容 结论 Node 文件批量重命名可以简化文件管理和组织的工作,提高工作...
(2)修改 Element UI 样式时,避免直接复制和修改 Element 的样式类,以免影响其他页面。应在当前页面内进行修改。 5. **Element 主题**: Element UI 提供了自定义主题的功能。你可以访问 `...
在使用过程中,根据提供的`BasicUtils-main`这个文件夹名,我们可以推断这是项目的主目录。在该目录下,你可能找到源代码文件(如`.js`或`.ts`),配置文件(如`package.json`),以及可能的测试文件和示例代码。`...
最后,提到的压缩包子文件"Groupomania-main"可能代表了项目的主文件夹或源代码目录。在开发环境中,项目经常被打包成ZIP文件进行分发,这样可以方便地下载和解压到本地进行工作。"main"通常指代项目的主要或核心...