NodeJS 无法在JSON中创建长于0x1fffffe8字符的字符串,parse?

iq0todco  于 2023-04-29  发布在  Node.js
关注(0)|答案(2)|浏览(338)

我有一个JSON文件,其中包含大小为914MB的JSON数据。我用fs-extra加载文件并解析它。但当我解析它时,得到错误为
无法创建长度超过0x1fffffe8个字符的字符串
下面是代码

const fs = require('fs-extra');
        const rawdata = fs.readFileSync('src/raw.json');
        const data = JSON.parse(rawdata);

我运行的项目与npm和运行我有下面的命令在package.json

"scripts": {
   
    "start:dev": "cross-env NODE_OPTIONS='--max-old-space-size=4096' ts-node -r tsconfig-paths/register ./src --env=development",
  
  }
vvppvyoh

vvppvyoh1#

0x1fffffe8正好是512 MB。

许多评论都是正确的:你已经达到了系统的极限我同意@Pointy的观点,它很可能是Node字符串长度限制。fs-extra与限制无关
在任何情况下,您都必须以块形式处理JSON。下面是不同的方法来做到这一点。

A:使用SAX风格的JSON解析器

您有许多解析器选项。为了让你开始,这里有几个我在NPM上找到的:

  • BFJ有一个walk函数,它执行SAX风格的解析。BFJ被存档,但每周仍有数百万次的下载量。
  • stream-json

B:实现Node Streams流水线

几乎可以肯定,您的海量JSON数据是根级别的数组。这种方法使用了一个解析器,它可以单独或批量处理数组中的每个元素,无论哪种方式都是有意义的。它基于非常强大和灵活的Node Streams API。
如果️你的数据不是一个JSON数组,而是一个连接的JSON对象流,那么它可能符合JSON Streaming protocol。参见下面的选项D

  • JSONStream允许您在其流解析中按路径或模式进行过滤。它被存档了,但每周仍有数百万的下载量
  • BFJ-除了支持上面提到的SAX风格的walk功能外,它还可以进行选择性对象级流传输:

match返回可读的对象模式流,并从输入JSON流中异步解析各个匹配项。

  • stream-json有一个Pick管道操作符,它可以从流中挑选所需的项,忽略其余项。很多其他选择。
  • jsonparse

C:手动分块

🚩 如果您的数据支持,这可能是最有效的。
该选项类似于B,不同之处在于,您不使用流解析器,而是自己进行分块。如果JSON数据数组的元素非常规则,这很容易做到。例如,每个元素正好占用N行。您可以轻松地提取它们而无需解析。
例如,如果您的数据如下所示:

{
  data: [
    { name: ...,
      address: ... },
    { name: ...,
      address: ... },
    { name: ...,
      address: ... },
    { name: ...,
      address: ... }
  ]
}

你的过程应该是这样的:
1.使用缓冲读取器读取文件。(不要将其全部同步读入内存)
1.丢弃前两行
1.分块读取文件,一次两行
1.如果一个块以{开头,则删除任何尾随逗号并解析每个{name:..., address:...}记录。
1.如果没有,则已到达数组的末尾。丢弃文件的其余部分或将其交给其他进程,如果您希望那里有其他数据。
具体细节将取决于您的数据。

D:使用JSON Streaming protocol解析器

JSON流协议是在流中连接的多个JSON对象的流。如果这就是您所拥有的,那么您应该使用支持该协议的解析器。

wgx48brx

wgx48brx2#

我通过删除zip文件修复了这个问题,在项目根文件夹中,我创建了项目的备份,该文件位于导致问题的根文件夹中。

相关问题