📜  Node.js 流完整参考(1)

📅  最后修改于: 2023-12-03 15:33:10.884000             🧑  作者: Mango

Node.js 流完整参考

简介

Node.js 流是一组在处理数据流时非常有用的抽象方法。使用流,我们可以在操作数据时同时节省内存和时间。Node.js 提供了几种不同类型的流,包括可读流(Readable)、可写流(Writable)、双工流(Duplex)和转换流(Transform)。

可读流(Readable)
创建可读流

要创建可读流,我们可以使用 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}`);
});
可写流(Writable)
创建可写流

要创建可写流,我们可以使用 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}`);
});
双工流(Duplex)

双工流是同时具有可读和可写功能的流。与单向流(可读或可写)不同,双工流可以同时读取和写入数据。

创建双工流

要创建双工流,我们可以使用 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}`);
});
转换流(Transform)

转换流对数据执行转换(例如压缩、解压缩或加密)。转换流是双工流的特殊类型,可以对输入和输出同时进行处理。

创建转换流

要创建转换流,我们可以使用 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 流的几种类型,并探讨了如何使用它们来在处理数据时节省内存和时间。我们还讨论了处理可读流、可写流、双工流和转换流的技术,并学习了如何处理结束和错误事件。