我有一个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",
}
2条答案
按热度按时间vvppvyoh1#
0x1fffffe8
正好是512 MB。许多评论都是正确的:你已经达到了系统的极限我同意@Pointy的观点,它很可能是Node字符串长度限制。
fs-extra
与限制无关在任何情况下,您都必须以块形式处理JSON。下面是不同的方法来做到这一点。
A:
使用SAX风格的JSON解析器您有许多解析器选项。为了让你开始,这里有几个我在NPM上找到的:
walk
函数,它执行SAX风格的解析。BFJ被存档,但每周仍有数百万次的下载量。B:
实现Node Streams流水线几乎可以肯定,您的海量JSON数据是根级别的数组。这种方法使用了一个解析器,它可以单独或批量处理数组中的每个元素,无论哪种方式都是有意义的。它基于非常强大和灵活的Node Streams API。
如果️你的数据不是一个JSON数组,而是一个连接的JSON对象流,那么它可能符合JSON Streaming protocol。参见下面的选项
D
。walk
功能外,它还可以进行选择性对象级流传输:match
返回可读的对象模式流,并从输入JSON流中异步解析各个匹配项。Pick
管道操作符,它可以从流中挑选所需的项,忽略其余项。很多其他选择。C:
手动分块🚩 如果您的数据支持,这可能是最有效的。
该选项类似于
B
,不同之处在于,您不使用流解析器,而是自己进行分块。如果JSON数据数组的元素非常规则,这很容易做到。例如,每个元素正好占用N行。您可以轻松地提取它们而无需解析。例如,如果您的数据如下所示:
你的过程应该是这样的:
1.使用缓冲读取器读取文件。(不要将其全部同步读入内存)
1.丢弃前两行
1.分块读取文件,一次两行
1.如果一个块以
{
开头,则删除任何尾随逗号并解析每个{name:..., address:...}
记录。1.如果没有,则已到达数组的末尾。丢弃文件的其余部分或将其交给其他进程,如果您希望那里有其他数据。
具体细节将取决于您的数据。
D:
使用JSON Streaming protocol解析器JSON流协议是在流中连接的多个JSON对象的流。如果这就是您所拥有的,那么您应该使用支持该协议的解析器。
wgx48brx2#
我通过删除zip文件修复了这个问题,在项目根文件夹中,我创建了项目的备份,该文件位于导致问题的根文件夹中。