首页 > 解决方案 > Node.js - 循环读取和写入数千/数百万个 JSON 文件

问题描述

我需要以最有效和最快速的方式处理大量文件。

读取 -> 处理 -> 写入(保存到同一个地方)。

我的问题是我的实现很慢,至少我是这么认为的。我花了半个晚上左右的时间来处理 600000 个文件。

我故意以同步方式完成它,如果这可以异步完成更好 - 我对解决方案持开放态度,我只是不认为处理大量仅重 1-3kb 的文件会花费那么长时间。

文件有简单的 JSON 数据,每个文件大小约为 1-3kb,就像我已经说过的那样。

这些文件位于单独的文件夹中,每个文件夹包含 300 个文件。我将它们分开以使其更有效和可用。

所以我们有大约 2000 个文件夹,每个文件夹有 300 个文件(1-3kb 大小)。

看看我的代码,给我你的想法。谢谢!

function test() {

    /**
     * Get list of folders and loop through
     */
    const folderList = fs.readdirSync(`../db`)

    for (const folder of folderList) {

        /**
         * Get list of files for each folder and loop through
         */
        const fileList = fs.readdirSync(`../db/${ folder }`)

        for (const filePath of fileList) {

            /**
             * try/catch block to handle JSON.parse errors
             */
            try {

                /**
                 * Read file
                 */
                const file = JSON.parse(fs.readFileSync(`../db/${ folder }/${ filePath }`))

                /**
                 * Process file
                 */
                processFile(file)

                /**
                 * Write file
                 */
                fs.writeFileSync(`../db/${ folder }/${ filePath }`, JSON.stringify(file), 'utf8')

            } catch (err) {

                console.log(err)

            }
        }
    }
}

我希望它运行得相当快,实际上这需要一段时间。

标签: javascriptnode.jsfs

解决方案


所以,在玩了一些东西之后,我想到了这样的事情:

const PromisePool = require('es6-promise-pool')

const list = require('./list.json')

let n = 0

let pool = new PromisePool(promiseProducer, 11)

pool.start()
    .then(function () {
        console.log('Complete')
    })

function promiseProducer(){

    console.log(n)

    if (n < list.length)
        return processFile(list[++n])
    else
        return null
}

这跑得相当快。不过,我还有一些问题。

  1. 任何人都可以编写自己的并发限制实现吗?没有图书馆等
  2. 像以前一样,如果我运行脚本并等待处理 20k(例如)文件,如果我停止脚本并重新运行,它会很快达到 20k(我们停止的地方),然后它会变慢。是什么原因?

推荐阅读