我有很多文件(百万)要从一个文件夹复制到另一个文件,但是基于某些解析选项,如果不遵守某些条件,则需要删除该文件。
我正在对文件的本地副本进行解析,因为在网络上解析(读取文件+解析)比在本地进行解析要慢。
我的代码如下:
for (let file of files) {
fs.copyFile(from, to, err => {
if (err) return;
parse(file);
});
}
parse
函数类似于:
parse = file => {
fs.readFile(file, (err, data) => {
//do some parsing
if (notOk) {
fs.unlink(file);
};
}
}
问题在于它正在执行所有copyFile
,并且似乎没有用unlink
执行回调,而且我真的需要在文件复制完成后立即取消链接,因为我可以没有足够的磁盘空间来首先复制所有文件。
我是否需要使用这些方法的Sync
版本?
谢谢
我本来期望这样的输出:
copyFile a
copyFile b
copyFile c
parsing a
copyFile d
unlink a
parsing b
copyFile e
...
但是相反,我拥有所有copyFile
并且没有任何解析/取消链接。
答案 0 :(得分:0)
我认为这正在发生,应对中的回调已完成,因此线程已完成,但是函数无法完成,您可以进行此同步,并且可以正常工作,并且更加清楚,但是其他方法是将功能转换为Promise,以便您可以返回Promise并等待它们。
您可以这样写。
const util = require('util');
const fs = require('fs');
const files = ['1.txt', '2.txt', '3.txt', '4.txt'];
//promisify all the fs functions to use.
const copyFilePromise = util.promisify(fs.copyFile);
const readFilePromise = util.promisify(fs.readFile);
const unlinkPromise = util.promisify(fs.unlink);
//make a parser function that return a promise.
const parse = (file) => {
return readFilePromise(file)
.then(() => {
//do some parsing
if(notOk)
return unlinkPromise(file)
});
};
//store all the promises in an array
let promises = []
//iterate for all the files using the promisify aproach of the functions
for (let file of files){
//add all the promises to an array of promises.
promises.push(copyFilePromise(from, to).then(parse(file)).catch(console.error));
}
//wait for all the promises to resolve.
Promise.all(promises);
答案 1 :(得分:0)
如果files
包含数百万个文件,则说明您正在开始数百万个并发复制操作,这可能使您的系统不堪重负。
相反,请考虑使用类似async.eachLimit
的方式来限制并发复制操作的数量。
未经测试的示例:
const async = require('async');
async.eachLimit(files, 10, (file, callback) => {
fs.copyFile(from, to, err => {
if (err) return callback(); // or pass `err`
parse(file, callback);
});
});
function parse(file, callback) {
fs.readFile(file, (err, data) => {
//do some parsing
if (notOk) {
fs.unlink(file, callback);
} else {
return callback();
}
})
}