在 Node 中,不可避免地还是会存在操作大文件的场景。由于 Node 的内存限制,操作大文件也需要小心,好在 Node 提供了 stream
模块用于处理大文件。
stream
模块是 Node 的原生模块,直接引用即可。 stream
继承自 EventEmitter
,具备基本的自定义事件功能,同时抽象出标准的事件和方法。它分可读和可写两种。Node中的大多数模块都有 stream 的应用,比如 fs 的 createReadStream()
和 createWriteStream()
方法可以分别用于创建文件的可读流和可写流, process
模块中的 stdin
和 stdout
则分别是可读流和可写流的示例。
由于V8的内存限制,我们无法通过 fs.readFile()
和 fs.writeFile()
直接进行大文件的操作,而改用 fs.createReadStream()
和 fs.createWriteStream()
方法通过流的方式实现对大文件的操作。下面的代码展示了如何读取一个文件,然后将数据写入到另一个文件的过程:
1 | let reader = fs.createReadStream('in.txt'); |
由于读写模型固定,上述方法有更简洁的方式,具体如下所示:
1 | let reader = fs.createReadStream('in.txt'); |
可读流提供了管道方法 pipe()
,封装了 data
事件和写入操作。通过流的方式,上述代码不会受到V8内存限制的影响,有效地提高了程序的健壮性。如果不需要进行字符串层面的操作,则不需要借助V8来处理,可以尝试进行纯粹的 Buffer 操作,这不会受到V8堆内存的限制。但是这种大片使用内存的情况依然要小心,即使V8不限制堆内存的大小,物理内存依然有限制。