gpt4 book ai didi

javascript - Node.js 异步查找具有相同内容的文件

转载 作者:行者123 更新时间:2023-12-03 04:25:00 25 4
gpt4 key购买 nike

目标:给定输入中的文件路径和文件路径数组,我需要检查数组中是否存在与输入文件相同的文件(即使名称不同)。我需要异步读取文件,如果找到相等的文件则停止(在这种情况下我不想读取数组中的所有文件)。

我只想使用 ecma6 功能,而不使用其他库。我正在使用node.js,因此比较文件足以使用 compare buffers function :

const fs = require("fs");

let buffer1 = fs.readFileSync(filePath1);
let buffer2 = fs.readFileSync(filePath2);
if (buffer1.compare(buffer2) === 0) {
console.log("Files are equal");
} else {
console.log("Files are different");
}

基本上,对于数组中的每个文件路径,我想使用如下函数顺序检查相等性(但使用异步读取):

function isFileEqual (fileInputBuffer, path) {
return new Promise((resolve, reject) => {
fs.readFile(path, (err, data) => {
if (err) {
resolve(false);
}

if (data.compare(fileInputBuffer) === 0) {
resolve(true);
} else {
resolve(false);
}
});
});
}

我想出了一个解决方案,利用 Promises.all 的“快速拒绝”属性,如果任何输入 promise 拒绝而不等待其他 promise 完成,这会导致立即拒绝:

const fs = require("fs");

let paths = ["file2", "file3", "file1_copy", "file4", "file5"];


checkIfFileAlreadyExistsAsync("file1", paths).then(path => {
console.log("\n", "File equal found at: ", path, "\n");
}).catch(err => {
console.log(err);
});



function checkIfFileAlreadyExistsAsync(filePath, paths) {

return new Promise( (rootResolve, rootReject) => {

fs.readFile(filePath, (err, inputBuffer) => {

if (err) {
rootReject(err);
return;
}


function isFileEqual(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, (err, data) => {

console.log("[isFileEqual]", path);

if (err) {
resolve();
}
else if (data.compare(inputBuffer) === 0) {
reject(path); // file equal found, reject fast!
} else {
resolve();
}
});
});
}



let promises = [];

// fill promises array
paths.forEach(path => {
promises.push(isFileEqual(path));
})



Promise.all(promises).then(values => {

rootReject(false);

})
.catch((path) => {

// use reject fast to resolve without wait the other promises to complete
rootResolve(path);

});

});

});
}

上述脚本的输出:

[isFileEqual] file2
[isFileEqual] file1_copy

File equal found at: file1_copy

[isFileEqual] file4
[isFileEqual] file3
[isFileEqual] file5

上述解决方案有效,但正如您所看到的,存在一个问题:无论是否已找到相同的文件,所有文件都会被读取。

我之前不知道,但是 Promise 一创建就会执行(我认为相反,为什么要这样实现?),因此我想使用如下的 Promise 工厂:

function promiseFactory(path) {
return function () {
return new Promise((resolve, reject) => {
fs.readFile(path, (err, data) => {

console.log("[isFileEqual]", path);

if (err) {
reject();
}
else if (data.compare(inputBuffer) === 0) {
resolve(true);
} else {
resolve(false);
}
});
});
};
}

并尝试按顺序运行 promise 。但我怎样才能做到这一点呢?或者还有其他方法吗?

最佳答案

我找到了使用递归的解决方案。基本上,我创建一个工厂数组(每个工厂返回一个返回 Promise 的函数),然后使用该数组作为递归函数的输入。如果找到相等的文件,则递归函数解析主 Promise(主函数返回的 Promise),否则它会递归调用自身,输入工厂数组和要创建的下一个 Promise 的索引。

const fs = require("fs");
let paths = ["file2", "file3", "file1_copy", "file4", "file5"];


checkIfFileAlreadyExistsAsync("file1", paths).then(result => {
console.log("SUCCESS", result);
}).catch(err => {
console.log("FAIL", err);
});


function checkIfFileAlreadyExistsAsync(filePath, paths) {

return new Promise((rootResolve, rootReject) => {

fs.readFile(filePath, (err, inputBuffer) => {

if (err) {
rootReject(err);
}



function compareFilePromiseFactory(path) {
return function() {
return new Promise((resolve, reject) => {
fs.readFile(path, (err, data) => {

console.log("Compare file: ", path, "\n");

if (err) {
resolve(false);
}
else if(data.compare(inputBuffer) === 0) {
resolve(true);
}
else {
resolve(false);
}
});
});
}
}



let factories = [];
paths.forEach(path => {
factories.push(compareFilePromiseFactory(path));
});




function findFile(factories, index) {

if (index == factories.length) {
rootReject(false);
return;
}

factories[index]().then(result => {

if (result) {
rootResolve(true);
}
else {
findFile(factories, index + 1);
}
});
}


findFile(factories, 0);


});
});
}

上面的脚本给出以下输出:

Compare file:  file2

Compare file: file3

Compare file: file1_copy

SUCCESS true

每个 Promise 都是按顺序创建的,但都是异步的。一旦找到相同的文件,它就会停止生成 promise 。不知道是否也可以迭代解决,您觉得如何?

关于javascript - Node.js 异步查找具有相同内容的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43783023/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com