我应该如何在 Node.js 中处理和使用大量文件?

问题描述 投票:0回答:1

我有一个包含大约 500,000 个 JSON 文件路径的数组。文件的平均大小为 20-100 KB。每个 JSON 文件都包含一个需要读取的数值并将其添加到累计总数中。

如果我在迭代中同步读取文件,处理速度很快就会变慢。如果我在迭代中异步读取文件,我会收到“打开的文件太多”错误。

我的问题是,什么方法、迭代和文件处理方法适合执行此任务?我对 Node.js 比较陌生,并且正在努力解决上述问题。

function readFiles(filePaths) {
    filePaths.forEach(filePath => {
        fs.readFile(filePath, 'utf8', (err, data) => {
            // do somthing
        });
    });
}

readFiles(filePaths); // it's an array of strings
node.js json largenumber
1个回答
0
投票

当您使用

filePaths.forEach
时,它会快速遍历大数组,每次它都会启动一个异步
fs.readFile
调用,该调用快速返回一个承诺,然后执行打开文件并在后台处理它的工作。这意味着您很快就会同时打开大量文件,并且遇到您所看到的问题。

要限制一次打开的文件数量,您需要确保不会同时创建太多异步调用。一种方法是使用 PromisePool(请参阅 https://www.npmjs.com/package/@supercharge/promise-pool)。这允许您将同时 Promise 的数量设置为 50 或任何适合您情况的值,并且它将在之前的文件完成时启动新文件读取。

使用

PromisePool
您的代码可能如下所示:

import { PromisePool } from '@supercharge/promise-pool'
function readFiles(filePaths) {
    return PromisePool
        .withConcurrency(50)
        .for(filePaths)
        .process(async (filePath) => {
             return fs.readFile(filePath, 'utf8', (err, data) => {
                 // do something
             }
        });
}

readFiles(filePaths); // it's an array of strings

本质上与您所拥有的流程相同,但通过使用

PromisePool.for().process()
,它将确保在任何时候只有特定数量处于活动状态。这应该可以防止您因一次打开太多文件而导致资源超载。

© www.soinside.com 2019 - 2024. All rights reserved.