Node.js 中的流(Streams)是一种处理读取和写入数据的抽象接口,它允许你以非阻塞的方式处理数据,这对于处理大文件或网络请求等 I/O 密集型任务非常有用。流主要分为四种类型:可读流(Readable)、可写流(Writable)、双工流(Duplex)和转换流(Transform)。
1. 可读流(Readable Streams)
可读流用于从源读取数据。数据源可以是文件、网络连接等。
常用函数:
read([size])
:从流中读取数据。不推荐直接使用,因为流的设计初衷是自动处理数据的流动。pipe(destination[, options])
:将可读流的数据流重定向到一个可写流。这是处理流数据最常见的方法之一。pause()
:暂停流中的数据读取。resume()
:恢复流的数据读取。on('data', callback)
:当流中有数据可读时,触发回调函数。on('end', callback)
:当没有更多数据可读时触发。on('error', callback)
:处理流中的错误。
2. 可写流(Writable Streams)
可写流用于将数据写入目标。目标可以是文件、网络连接等。
常用函数:
write(chunk[, encoding][, callback])
:向流中写入数据。chunk
是要写入的数据,encoding
是数据的编码(如果chunk
是字符串),callback
是写入完成后的回调函数。end([chunk][, encoding][, callback])
:结束写入过程。可选的chunk
和encoding
允许在结束前再写入一些数据。on('drain', callback)
:当可以继续写入数据时被调用(即流内部的缓冲区为空时)。on('finish', callback)
:当所有数据都被写入底层系统时触发。on('error', callback)
:处理流中的错误。
3. 双工流(Duplex Streams)
双工流既是可读流也是可写流。例如,TCP 套接字连接。
继承自可读流和可写流的属性和方法。
4. 转换流(Transform Streams)
转换流是特殊的双工流,其输出数据是基于输入数据的某种转换。例如,zlib.createGzip()
用于创建 gzip 压缩流。
常用函数(继承自双工流):
_transform(chunk, encoding, callback)
:这是转换流的核心方法,需要被重写以实现自定义的转换逻辑。chunk
是要转换的数据块,encoding
是数据的编码(如果chunk
是字符串),callback
是转换完成后的回调函数。
const fs = require('fs');
const readableStream = fs.createReadStream('input.txt');
const writableStream = fs.createWriteStream('output.txt');
readableStream.pipe(writableStream);
readableStream.on('end', () => {
console.log('文件读取完毕');
});
writableStream.on('finish', () => {
console.log('文件写入完毕');
});
在这个例子中,我们使用 fs.createReadStream
创建一个可读流来读取 input.txt
文件,然后使用 fs.createWriteStream
创建一个可写流来写入 output.txt
文件。通过 pipe
方法,我们实现了从可读流到可写流的数据流重定向。当可读流结束(end
事件)时,表示文件已读取完毕;当可写流完成写入(finish
事件)时,表示数据已完全写入目标文件。