fs.copy失败,大量的图像,less数工作

我有一组文件名,我试图从一个目录复制到另一个。 文件名是在async series链中的函数中构造的,然后在最终函数中使用fs.copy复制fs.copy 。 脚本也在十个不同的目录上运行,所以我看起来像这样。 它是简化的,但function是相同的。

 var dirs = [{ 'src': 'dir1', 'dest': 'dest/dir1', 'files': [] }, { 'src': 'dir2', 'dest': 'dest/dir2', 'files': [] }, { 'src': 'dir3', 'dest': 'dest/dir3', 'files': [] }, { 'src': 'dir4', 'dest': 'dest/dir4', 'files': [] }]; async.series([function(callback){ //get files dirs.forEach(function(currentSrc){ fs.readdirSync(currentSrc); }); callback(); }, function(callback){ //make dest dirs with dirs.forEach and fs.mkdir callback(); }, function(callback){ var src , dest; dirs.forEach(funtion(dir){ dir.files.forEach(function(file){ src = path.join(dir.src, file); dest = path.join(dir.dest, file); fs.copy(src, dest, {replace: false}, function(err) { if (err){ console.log('error copying file: ', err); } }); }); }]); 

这适用于less量的文件,但是当我用包含大约400MB的目录尝试它时,它失败了。 所有的文件似乎都在目的地,但有名称(这是正确的)以外的数据,但每个的文件大小为0.为什么这将工作less量的文件,但不是大?

更新。 我得到错误

events.js:85扔呃; //未处理“错误”事件

更新:我现在使用@Jacob提供的策略,我拥有的是:

 var dirs = [{ 'src': 'src/1', 'dest': 'waterfallDest1', 'files': [] }, { 'src': 'src/2', 'dest': 'waterfallDest2', 'files': [] }, { 'src': 'src/3', 'dest': 'waterfallDest3', 'files': [] }, { 'src': 'src/4', 'dest': 'waterfallDest4', 'files': [] }]; async.eachLimit(dirs, 1000, function (dir, cb) { async.waterfall([ function (cb) { fs.mkdir(dir.dest, cb); }, function (cb) { fs.readdir(dir.src, cb); }, function (files, cb) { async.eachLimit(files, 10, function (file, cb) { var src = path.join(dir.src, file); var dest = path.join(dir.dest, file); try { // In case fs.copy is indeed throwing an error fs.copy(src, dest, {replace: false}, cb); } catch (err) { cb('try-catch err ', err); } }, cb); } ], cb); }, function (err) { if (err) { console.log('Some error happened:\n' + err.stack); } }); 

这是成功创build所有的目录,并成功地将文件传输到第一个目录,但每个后续的目录都充满了0K图像。

根据文档 “您可以使用try / catch来处理exception,或允许它们冒泡”。

  try { fs.copy(src, dest, {replace: false}); } catch(e) { if ( e.code != 'EEXIST' ) throw e; // I'm guessing here that this // is your problem. } 

值得一提的是,底层的库ncp是FS中零星callback的责任。 FS问题 如果 NCP幕后已经多次调用一个单一文件的callback,那么第二个callback将抛出一个exception…文件已经存在。

您需要为您的async.series调用进行最后的callback:

 async.series([ function (callback) { dirs.forEach(function (currentSrc) { fs.readdirSync(currentSrc); }); callback(); }, function (callback) { //make dest dirs with dirs.forEach and fs.mkdir callback(); }, function(callback) { var src, dest; dirs.forEach(funtion(dir){ dir.files.forEach(function(file){ src = path.join(dir.src, file); dest = path.join(dir.dest, file); fs.copy(src, dest, {replace: false}, function(err) { if (err){ console.log('error copying file: ', err); // Did you want to do callback(err)? } }); }); }) // Somewhere, this needs to call back. } ], function (err, result) { if (err) { // One of the steps had an error; handle it. } }); 

以下是您的代码如何使用async.each来避免所有这些循环。 它还包括限制,以避免操作系统一次打开太多的文件:

 async.eachLimit(dirs, 10, function (dir, cb) { async.waterfall([ function (cb) { fs.mkdir(dir.dest, cb); }, function (cb) { fs.readdir(dir.src, cb); }, function (files, cb) { async.eachLimit(files, 10, function (file, cb) { var src = path.join(dir.src, file); var dest = path.join(dir.dest, file); try { // In case fs.copy is indeed throwing an error fs.copy(src, dest, {replace: false}, cb); } catch (err) { cb(err); } }, cb); } ], cb); }, function (err) { if (err) { console.log('Some error happened:\n' + err.stack); } });