fs.大量图像复制失败,少量图像复制有效
fs.copy fails with large number of images, works for small number
我有一个文件名数组,我试图将其从一个目录复制到另一个目录。在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把呃;//未处理的'error'事件
更新:我现在使用的是@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图像。
根据文档"您可以使用try/catch来处理异常或允许它们冒泡。"
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中零星回调的罪魁祸首。如果 ncp在后台为一个文件调用了不止一次的回调,那么第二次回调将抛出一个异常…文件已经存在
您需要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);
}
});
相关文章:
- 复制图像路径以单击它
- 当页面包含指向一个图像的多个链接时,fancyBox会复制缩略图辅助图像
- 使用JavaScript从网页复制HTML代码或图像链接
- 如何使用PHP、提交和单选按钮复制/重命名/覆盖图像
- HTML将图像从画布复制到另一个画布
- Anythingsslider+Fancybox复制图像
- 是否可以将画布图像复制到剪贴板
- 使用Jquery将剪贴板图像复制到网页中
- 如何禁止复制浏览我的网站的图像
- 将javascript制作的图像复制到剪贴板
- 如何在 MobileSafari 中接收复制的图像
- 如何将画布图像数据复制到论文.js 光栅对象
- 将图像复制到剪贴板,在 Firefox 和 Chrome 中不起作用
- 仅在Chrome中使用javascript将图像复制到剪贴板
- 需要有关使用 ASP.Net 或 JavaScript 将图像复制到网站剪贴板的帮助
- 我如何使用docpad的缩略图插件而不将源图像复制到“;输出”;
- 如何用图像复制字体?
- 将图像复制到剪贴板
- fs.大量图像复制失败,少量图像复制有效
- 将HTML画布作为图像复制到剪贴板