我有一个文件名数组,我试图从一个目录复制到另一个目录。文件名在async
series
链中的函数中构建,然后在最终函数中,使用fs.copy
复制它们。该脚本也在十个不同的目录上运行,所以我看起来像这样。它是简化的,但功能相同。
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);
}
});
});
}]);
这适用于少量文件,但是当我尝试使用包含大约400MB的目录时,它失败了。所有文件似乎都在目的地,但是除了名称之外还有数据(这是正确的),但每个文件的文件大小为0.为什么这对少量文件起作用,但不是很大?
更新。我收到了错误
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);
}
});
这是成功创建所有目录,并成功将文件传输到第一个目录,但每个后续目录都填充了0k图像。
答案 0 :(得分:0)
您需要对async.series
电话进行最终回调:
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);
}
});
答案 1 :(得分:0)
Per the documentation“您可以使用try / catch来处理异常或允许它们冒泡。”
function load() {
};
对于它的价值,底层库ncp应归咎于fs内的零星回调。 fs issues IF ncp幕后花絮多次为单个文件调用回调,然后第二次回调会抛出一个异常......文件已经存在。