使用ncp复制文件时出现丢失问题,fs.readdir检测结果一致
解决ncp批量复制文件丢失的问题
我之前处理大文件批量复制时也碰到过ncp丢文件的情况,结合你的代码和场景,大概率是异步处理逻辑或ncp默认配置的问题,给你几个针对性的解决方案:
1. 降低ncp的并发数,避免系统资源过载
ncp默认的并发复制数较高(默认是16),当复制大量文件时,系统IO可能跟不上,导致部分文件复制被静默跳过。你可以手动降低并发数:
const ncp = require('ncp').ncp; // 全局设置并发限制 ncp.limit = 10; // 或者在调用时传入配置 ncp(sourcePath, destPath, { concurrency: 10 }, (err) => { // 回调逻辑 });
2. 改用Promise版本+async/await,确保复制完全完成
回调模式下很容易出现逻辑时序问题(比如你可能在复制未完成时就执行了验证),用ncp的Promise配合async/await能更可靠地等待复制结束:
const ncp = require('ncp').ncp; const fs = require('fs').promises; const path = require('path'); async function safeCopyResources() { try { const source = path.join(req.body.uploadPath, req.body.packageName, resourceDirectoryName); const target = path.join(req.body.uploadPath, req.body.packageName); // 复制时开启stopOnError,遇到错误立即终止,避免部分文件丢失 await ncp(source, target, { concurrency: 10, stopOnError: true }); // 复制完成后再执行验证 await validateCopy(source, target); console.log('所有文件复制完成且验证通过!'); } catch (err) { devMode.report(`复制失败:${err.message}`); } } // 递归验证所有文件(包括子目录) async function validateCopy(sourceDir, targetDir) { // 递归读取所有文件和目录 const getRecursiveFiles = async (dir) => { const entries = await fs.readdir(dir, { withFileTypes: true, recursive: true }); return entries.map(entry => path.relative(dir, path.join(entry.parentPath, entry.name))); }; const sourceFiles = await getRecursiveFiles(sourceDir); const targetFiles = await getRecursiveFiles(targetDir); const missing = sourceFiles.filter(file => !targetFiles.includes(file)); if (missing.length > 0) { throw new Error(`发现丢失文件:${missing.join(', ')}`); } } // 执行复制 safeCopyResources();
3. 监听ncp的错误事件,捕获静默失败
有些文件复制失败(比如权限不足、文件被占用)可能不会触发最终的回调err,而是通过error事件抛出,你可以添加监听来捕获这些问题:
const copyTask = ncp(sourcePath, destPath, { concurrency: 10 }, (err) => { if (err) { devMode.report(`复制回调错误:${err.message}`); } }); // 监听所有复制过程中的错误 copyTask.on('error', (err) => { devMode.report(`文件复制错误:${err.message},涉及文件:${err.file}`); });
4. 检查你的验证逻辑是否完整
你之前用fs.readdir验证时,默认是不递归读取子目录的,如果源文件夹有多层子目录,你只会验证一级目录的文件,自然会误以为子目录文件丢失。上面的validateCopy函数用了recursive: true参数,能递归获取所有层级的文件,确保验证准确。
内容的提问来源于stack exchange,提问作者Mahmoud Niypoo
相关产品推荐
相关产品推荐

