Node.js 使用 fs.readFileSync 读取大文件

Node.js read big file with fs.readFileSync

我尝试在具有 96GB RAM 的服务器上使用 fs.readFileSync 将大文件 (~6Gb) 加载到内存中。

问题是它失败并显示以下错误消息

RangeError: Attempt to allocate Buffer larger than maximum size: 0x3fffffff bytes

不幸的是,我没有找到增加 Buffer 的方法,它似乎是一个常数。

如何克服这个问题并使用 Node.js 加载大文件?

谢谢!

来自 joyent FAQ:

What is the memory limit on a node process?

Currently, by default v8 has a memory limit of 512mb on 32-bit systems, and 1gb on 64-bit systems. The limit can be raised by setting --max_old_space_size to a maximum of ~1024 (~1 GiB) (32-bit) and ~1741 (~1.7GiB) (64-bit), but it is recommended that you split your single process into several workers if you are hitting memory limits.

如果您更详细地说明文件中的内容以及您正在使用它做什么,我们可能会提供一些关于如何分块使用它的想法。如果它是纯数据,那么您可能希望使用数据库并让数据库根据需要处理从磁盘获取内容并管理内存。

这是最近对该问题的讨论:https://code.google.com/p/v8/issues/detail?id=847

而且,a blog post 声称您可以编辑 V8 源代码并重建节点以消除内存限制。请自行决定是否尝试。

我在尝试加载 6.4G 视频文件以创建文件哈希时也遇到了同样的问题。 我通过 fs.readFile() 读取整个文件,它导致错误 RangeError [ERR_FS_FILE_TOO_LARGE]。然后我使用流来做:

let hash = crypto.createHash('md5'),
    stream = fs.createReadStream(file_path);

stream.on('data', _buff => { hash.update(_buff, 'utf8'); });
stream.on('end', () => { 
    const hashCheckSum = hash.digest('hex');
    // Save the hashCheckSum into database.
});

希望对您有所帮助。