#node.js #fs #readfile #async.js
#node.js #fs #readfile #async.js
Вопрос:
Я хотел знать, какой наиболее эффективный метод одновременного чтения нескольких файлов. у меня есть массив путей к файлам, и я хочу создать массив данных, используя файл чтения fs (не AsyncRead и не используя функцию обратного вызова), упорядоченный в соответствии с индексом массива путей. мне нужно прочитать три файла одновременно, и я не могу найти, как одновременно читать файлы.
Я нашел этот метод, но не могу понять, читает ли он файлы одновременно, и если да, то как:
***function simultaneouslyRead(filePath1, filePath2){
var async = require('async'),
fs = require('fs'),
files = [filePath1, filePath2];
async.map(files, fs.readFile, function(err, files) {
if(err) {
throw err;
}
files.forEach(function(file) {
console.log(file.toString());
});
});
}***
Ответ №1:
Мы могли бы использовать util.promisify для создания версии fs.ReadFile на основе обещаний, а затем использовать Promise.all для чтения всех файлов в массив, что-то вроде этого:
const fs = require("fs");
const { promisify } = require("util");
const promiseReadFile = promisify(fs.readFile);
async function readFiles(files) {
const fileArray = await Promise.all(files.map(file => promiseReadFile(file)));
console.log("File contents:", fileArray);
return fileArray;
}
readFiles(['file1.txt', 'file2.txt']);
Файловый массив будет содержать массив буферов после считывания данных.
Пересмотренная версия, включающая ошибки из-за любых сбоев чтения:
const fs = require("fs");
function promiseReadFile(path, options = {}) {
return new Promise(resolve => {
fs.readFile(path, options, (err, data) => resolve({ err, data }));
});
}
async function readFiles(files) {
const fileArray = await Promise.all(files.map(file => promiseReadFile(file)));
console.log("File contents:", fileArray);
return fileArray;
}
readFiles(['file1.txt', 'file2.txt', 'file3.txt']);
Комментарии:
1. Ваши решения в порядке, но если он решит записать обратно file1 и file2, вероятно, не будут точно такими же, верно?
2. Мы считываем каждый файл в буфер в том виде, в каком он находится в данный момент, эффективно делая моментальные снимки содержимого. Конечно, файлы могут измениться до или после. Если бы кто-то хотел заблокировать файлы, можно было бы пойти по этому пути, хотя я считаю, что на данный момент это выходит за рамки вопроса.
3. ваше решение отличное, но что, если в одном файле будет ошибка (не найден, cloudnt открыт и т. Д.), Я хочу, Чтобы конечным результатом было содержимое открытых файлов и ошибки неоткрытых файлов, как перехватить ошибки при чтении одновременно?
4. Это хороший момент. В первой версии, если мы столкнемся с какими-либо ошибками, мы получим отклонение обещания при вызове Promise.all. Мы можем создать пользовательскую функцию promiseReadFile, которая попытается прочитать все файлы и сохранить любые ошибки, возникающие в результате этого. В этом случае мы получим массив результатов: [{data: {}, err: {}, … etc]
Ответ №2:
const fs= require('fs').promises;
async function readFiles(files) {
const results = await Promise.allSettled(files.map(file=> fs.readFile(file)));
console.log(results);
return results;
}
readFiles(['1.txt', '2.txt', '3.txt']);