是否有用于异步 JSON 解析器的 Node 模块,它不会将整个 JSON 字符串加载到内存中?

Posted

技术标签:

【中文标题】是否有用于异步 JSON 解析器的 Node 模块,它不会将整个 JSON 字符串加载到内存中?【英文标题】:Is there a Node module for an async JSON parser that does not load the entire JSON string into memory? 【发布时间】:2014-12-12 16:54:01 【问题描述】:

我意识到there are a ton of Node modules that provide an async API for parsing JSON,但他们中的许多人似乎读取整个文件或流到内存中,构造一个巨大的字符串,然后将其传递给JSON.parse()。这就是the second answer to "How to parse JSON using NodeJS?" suggests 所做的,也正是jsonfile module 所做的。

构造一个巨大的字符串正是我想要避免的。我想要这样的 API:

parseJsonFile(pathToJsonFile): Promise

返回的Promise 解析为解析后的 JSON 对象。此实现应使用恒定数量的内存。我对在解析各种片段时广播事件的任何类似 SAX 的东西不感兴趣:只是最终结果。

我认为jsonparse 可以做我想做的事(它显然包含了不使用JSON.parse() 解析JSON 的逻辑),但是README.md 中没有简单的例子,one file in the examples directory 似乎过于复杂。

【问题讨论】:

【参考方案1】:

我编写了一个模块来执行此操作:BFJ(Big-Friendly JSON)。它导出了一堆在不同抽象级别上运行的函数,但它们的核心都是异步和流式传输。

***别是两个用于读取和写入文件系统的函数,bfj.readbfj.write。他们每个人都返回一个承诺,所以你这样称呼他们:

var bfj = require('bfj');

// Asynchronously read from a JSON file on disk
bfj.read(path)
  .then(data => 
    // :)
  )
  .catch(error => 
    // :(
  );

// Asynchronously write to a JSON file on disk
bfj.write(path, data)
  .then(data => 
    // :)
  )
  .catch(error => 
    // :(
  );

在这一层还有一个用于将数据序列化为 JSON 字符串的函数,称为 bfj.stringify

// Asynchronously serialize data to a JSON string
bfj.stringify(data)
  .then(json => 
    // :)
  )
  .catch(error => 
    // :(
  );

下面是两个更通用的读取和写入流的函数,bfj.parsebfj.streamify。这些作为更高级别函数的基础,但您也可以直接调用它们:

// Asynchronously parse JSON from a readable stream
bfj.parse(readableStream).
  .then(data => 
    // :)
  )
  .catch(error => 
    // :(
  );

// Asynchronously serialize data to a writable stream of JSON
bfj.streamify(data).
  .pipe(writableStream);

在最低级别,有两个函数类似于 SAX 解析器/序列化器,bfj.walkbfj.eventify。您不太可能想直接调用它们,它们只是更高级别实现的核心。

它是开源的并获得 MIT 许可。欲了解更多信息,请查看the readme。

【讨论】:

Phil Booth:BFJ 的 API 看起来很棒!我质疑的一件看似微不足道的事情是check-types 的价值。 BFJ 只对模块进行了 13 次调用,其中一半似乎可以用typeof 检查替换。我不确定这是否值得额外的 20K。此外,check-types 的发布版本似乎附带了src/check-types.min.js,这将节省一些加载时间,但package.json 中的"main" 仍然指向src/check-types.js,因此您最终会加载更大的版本,无论如何。【参考方案2】:

jsonparse 是一个流式 json 解析器,示例代码已经展示了使用 Node 流的最低限度。

    client.request() 更改为fs.createReadStream()。 在文件读取流上设置on('data') 侦听器,类似于示例中on('response') 中的内容。

【讨论】:

jsonparse 缺乏文档让我感到不安。 examples 中只有一个文件,而且它甚至看起来都不起作用,因为有 require('./colors') 之类的东西,但没有 colors.js 文件。

以上是关于是否有用于异步 JSON 解析器的 Node 模块,它不会将整个 JSON 字符串加载到内存中?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Node.js 解析 JSON? [关闭]

如何使用 json 解析器的 boost property_tree 创建空数组节点

如何通过node.js中的JSONStream模块解析一个大的、换行符分隔的JSON文件?

在 Node.js 中使用原生 ES 模块方法解析

从 node.js 中的变量解析 CSV 表

在 Node.js 中解析没有 ID 或 CSS 选择器的 HTML 表格