📅  最后修改于: 2023-12-03 15:33:10.884000             🧑  作者: Mango
Node.js 流是一组在处理数据流时非常有用的抽象方法。使用流,我们可以在操作数据时同时节省内存和时间。Node.js 提供了几种不同类型的流,包括可读流(Readable)、可写流(Writable)、双工流(Duplex)和转换流(Transform)。
要创建可读流,我们可以使用 fs.createReadStream()
方法。此方法将返回一个新的可读流实例。
const fs = require('fs');
const readStream = fs.createReadStream('file.txt');
我们可以将可读流传递给其他的 API,例如 HTTP 响应或转换流(后面会介绍到)。
我们可以监听可读流的 data
事件来处理数据。当我们监听data
事件时,数据将被读取并传输到回调函数中。
readStream.on('data', (chunk) => {
console.log(`Received ${chunk.length} bytes of data.`);
});
我们可以使用 readStream.pause()
方法来暂停可读流的数据传输。当我们准备好处理更多数据时,可以调用 readStream.resume()
方法恢复数据传输。
readStream.on('data', (chunk) => {
readStream.pause();
console.log(`Received ${chunk.length} bytes of data.`);
readStream.resume();
});
当可读流已无可用数据时,它将触发 end
事件。我们可以监听该事件来执行最终操作。
readStream.on('end', () => {
console.log('Done reading data.');
});
当可读流遇到错误时,它将触发 error
事件。我们可以监听该事件来执行错误处理操作。
readStream.on('error', (err) => {
console.error(`An error occurred: ${err.message}`);
});
要创建可写流,我们可以使用 fs.createWriteStream()
方法。此方法将返回一个新的可写流实例。
const fs = require('fs');
const writeStream = fs.createWriteStream('output.txt');
我们可以将数据写入可写流中,以使它们存储在文件中。也可以将可写流传递给其他 API。
我们可以使用 writeStream.write()
方法将数据写入可写流中。如果写入成功,则该方法将返回 true
。否则,它将返回 false
。
const data = 'Hello, world!';
const success = writeStream.write(data);
if (success) {
console.log(`Data (${data.length} bytes) was written successfully.`);
} else {
console.log('Data could not be written at this time.');
}
当我们完成向可写流写入数据时,我们应该调用其 end()
方法。这将通知可写流,它可以进行清理操作。
writeStream.end();
当可写流遇到错误时,它将触发 error
事件。我们可以监听该事件来执行错误处理操作。
writeStream.on('error', (err) => {
console.error(`An error occurred: ${err.message}`);
});
双工流是同时具有可读和可写功能的流。与单向流(可读或可写)不同,双工流可以同时读取和写入数据。
要创建双工流,我们可以使用 stream.Duplex()
构造函数。我们需要实现 read()
和 write()
方法来处理数据。
const { Duplex } = require('stream');
class MyDuplex extends Duplex {
constructor(options) {
super(options);
}
_read(size) {
// Read data from the source and push it to the readable side of the duplex stream
}
_write(chunk, encoding, callback) {
// Write data to the destination
callback();
}
}
const myDuplex = new MyDuplex();
我们可以使用与可读流和可写流相同的方式使用双工流。但是,需要注意的是,在处理数据时,我们需要同时处理读取和写入的数据。
myDuplex.on('data', (chunk) => {
console.log(`Received ${chunk.length} bytes of data.`);
});
const data = 'Hello, world!';
myDuplex.write(data);
与可读流和可写流一样,双工流也需要处理结束和错误事件。
myDuplex.on('end', () => {
console.log('Done processing data.');
});
myDuplex.on('error', (err) => {
console.error(`An error occurred: ${err.message}`);
});
转换流对数据执行转换(例如压缩、解压缩或加密)。转换流是双工流的特殊类型,可以对输入和输出同时进行处理。
要创建转换流,我们可以使用 stream.Transform()
构造函数。我们需要实现 transform()
方法来处理数据。
const { Transform } = require('stream');
class MyTransform extends Transform {
constructor(options) {
super(options);
}
_transform(chunk, encoding, callback) {
// Transform the chunk and push it to the readable side of the transform stream
callback();
}
}
const myTransform = new MyTransform();
我们使用与双工流相同的方式使用转换流。但是,需要注意的是,我们需要同时处理输入和输出的数据。
myTransform.on('data', (chunk) => {
console.log(`Received ${chunk.length} bytes of data.`);
});
const data = 'Hello, world!';
myTransform.write(data);
与可读流、可写流和双工流一样,转换流也需要处理结束和错误事件。
myTransform.on('end', () => {
console.log('Done processing data.');
});
myTransform.on('error', (err) => {
console.error(`An error occurred: ${err.message}`);
});
在本文中,我们介绍了 Node.js 流的几种类型,并探讨了如何使用它们来在处理数据时节省内存和时间。我们还讨论了处理可读流、可写流、双工流和转换流的技术,并学习了如何处理结束和错误事件。