json 如何在Node.js中处理大量文件?

olhwl3o2  于 12个月前  发布在  Node.js
关注(0)|答案(1)|浏览(154)

我有一个包含大约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
nimxete2

nimxete21#

当你使用filePaths.forEach时,它会快速地遍历这个大数组,每次它都会启动一个fs.readFile调用,这个调用会快速返回一个promise,然后在后台打开文件并处理它。这意味着你很快就会同时打开大量的文件,你就会看到你所看到的问题。
要限制一次打开的文件数量,您需要确保不会同时创建太多的javascript调用。一种方法是使用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(),它将确保在任何时候只有特定数量的活动。这应该可以防止您一次打开太多文件而导致资源过载。

相关问题