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

6
我尝试使用fs.readFileSync将一个大文件(约6GB)加载到拥有96GB RAM的服务器内存中。
问题是它会出现以下错误信息:

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

不幸的是,我没有找到如何增加Buffer大小的方法,似乎它是一个常数。
我该如何解决这个问题并在Node.js中加载大文件呢?
谢谢!

你可能想要分块处理文件。你想用这个文件做什么?你真的需要一次性将整个文件加载到内存中吗? - jfriend00
是的,我需要一次性在RAN中获取整个文件。该文件包含一个大哈希值,我需要处理整个哈希值。 - com
你说的“包含一个大哈希”是什么意思?是指它包含了要放入哈希表中的数据吗?为什么不能分块处理呢? - jfriend00
2个回答

10

在创建文件哈希时,我尝试加载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.
});

希望它有所帮助。


谢谢朋友。 - Stepan Yakovenko

7
joyent FAQ得知:
当前默认情况下,32 位系统上的 v8 内存限制为 512MB,64 位系统上为 1GB。你可以通过将 --max_old_space_size 设置为最大值 ~1024 (~1 GiB)(32 位)和 ~1741 (~1.7GiB)(64 位)来增加此限制,但如果遇到内存限制问题,建议将单个进程拆分为多个工作进程。
如果您展示有关文件内容和操作的更多详细信息,我们可能可以提供一些有关如何以分块方式处理的想法。如果这是纯数据,则应该使用数据库,并让数据库负责根据需要从磁盘获取事物并管理内存。
这里是一个比较近期的讨论:https://code.google.com/p/v8/issues/detail?id=847 此外,这篇博文称,您可以编辑 V8 源代码并重新构建 node 以删除内存限制。但请自行决定是否尝试。

非常感谢您的回答。这些文件包含大词汇的词向量,其中每个单词都映射到一个300维的向量。主要任务是监督分类,其中训练集是一个大语料库,在这个任务中我需要用适当的向量替换每个单词。 - com
@fog - 我不能说我完全理解你在做什么,但我认为你需要在某种数据库中管理这6GB的数据,并使用数据库在需要时查找和获取数据的片段。或者,也许node.js并不是这项工作的正确工具。 - jfriend00
我尝试使用Redis与这个集合,但即使我已经使用了缓冲向量,它仍然非常慢。 - com
我不确定这是否准确。如果我有一个大小为3.6GB的文件,并使用fs.readFileSync('file.txt'),那么它会抛出RangeError [ERR_FS_FILE_TOO_LARGE]: File size (3941361242) is greater than 2 GB(node 15.14)。我可以使用Buffer.alloc分配一个大于2GB的缓冲区,并使用NODE_OPTIONS='--max-old-space-size=7000',但没有改变。 - Colin D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接