【问题标题】:Cannot create a string longer than 0x1fffffe8 characters in JSON.parse?无法在 JSON.parse 中创建长度超过 0x1fffffe8 个字符的字符串?
【发布时间】:2021-09-14 16:39:26
【问题描述】:

我有一个 JSON 文件,它的 json 数据大小为 914MB。我用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",
  
  }

【问题讨论】:

  • 您的服务器进程没有足够的内存。操作系统对单个进程可以消耗的资源施加限制。通常有一些方法可以指示操作系统应该为您的进程提供更多内存,但如果不知道您在做什么,就不可能提供更多信息。
  • 我使用过非常大的数据库,处理 900MB JSON 文件从来都不是我必须要做的事情。一方面,JSON 是一种真的低效的存储格式。
  • See this Node changelist.。 Node 的最大字符串长度约为 512MB,并且无法更改。它是 Node 架构的一部分。
  • 尝试使用流式 JSON 解析器。
  • 是的,流式解析器会很好,但如果代码开始组装数据结构本身时可能涉及另一个内存限制,我不会感到惊讶。同样,了解应用程序详细信息可能会让人们为 架构 更改提供建议。

标签: javascript node.js json npm


【解决方案1】:

0x1fffffe8 正好是 512MB。

许多评论是正确的:您遇到了系统限制。我同意@Pointy,它很可能是节点字符串长度限制。 fs-extra has nothing to do with the limit

无论如何,您都必须分块处理该 JSON。

几乎可以肯定,您的海量 JSON 数据是根级别的数组。因此,如果您使用流/SAX 解析器,您可以单独或批量处理该根数组中的每个元素,无论哪个有意义。

ℹ️您可能不想要只支持JSON Streaming protocol 的流解析器,因为该协议是为流中连接的多个 JSON 对象的流而设计的。但据我所知,你有一个巨大的整体 JSON 对象,很可能是我上面提到的根数组。

您有许多解析器选项。为了帮助您入门,以下是 NPM 上使用率最高的那些:

如果性能很关键

如果您知道源 JSON 的格式非常规则,例如根数组中的每条记录都是 N 行长,最有效的方法可能是通过缓冲读取器读取原始行,每 N 行抓取一次(调整顶部根数组的开头行),然后 JSON.parse那些单独的(在删除逗号分隔根数组条目之后。只是一个原始的想法。我从来没有做过!

【讨论】:

  • 我已经尝试了大多数选项,但它们不起作用。
  • 你是什么意思他们不工作?请详细说明。我无法帮助你发表这样的评论。
  • 你的情况是一个很常见的编程问题。这一点都不特别。你肯定没有做正确的事情。您是否仍在尝试将其作为一个字符串加载到内存中?如果是,那么您不理解我们所说的内容,也不理解我为您提供的解决方案,无论您尝试什么,您都会不断收到相同的错误。您需要分块处理它,而不是使用备用 JSON 解析器将其加载到 string 中。
  • 试过“大多数”?此答案中链接的stream-json 适用于巨大的 JSON 文件。
猜你喜欢
  • 2022-11-10
  • 1970-01-01
  • 2021-06-20
  • 2020-11-05
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 2012-09-08
相关资源
最近更新 更多