文章目录
- Node IO操作
- 概述
- 流的基本类型
- 可读流
- 读取模式
- 可读流状态
- 创建可读流
- 使用可读流
- 暂停和恢复
- 绑定可写流
- 可写流
- 创建可写流
- 使用可写流
- 关闭流
- 缓冲数据
- 可读可写流
- 转换流
Node IO操作
概述
在 Node.js 中,I/O(输入/输出)操作是异步的,这意味着它们不会阻塞主线程,允许其他代码继续执行。Node.js 提供了多种处理 I/O 操作的方式,包括文件系统操作、网络请求、数据库查询等。
Node.js 中的流是处理 I/O 操作的一种高效方式,特别是当处理大量数据时。流可以分为可读流、可写流、双工流和转换流。
流的基本类型
- Readable:可读流
- Writable:可写流
- Duplex:双工流,可读可写流
- Transform:转换流
可读流
读取模式
可读流有2种读取模式:
- flowing:流动模式
- paused:暂停模式
可读流状态
可读流有3种状态:
- null:初始状态
- true:流动状态
- false:非流动状态
创建可读流
// 使用stream模块
const stream = require("stream");
const readable = new stream.Readable();
// 使用fs模块
const fs = require("fs");
const read = fs.createReadStream("file.txt");
使用可读流
- setEncoding():设置编码格式。
- pause():暂停流。
- resume():恢复流。
- ispaused():是否暂停。
- destroy():销毁流。
- pipe():绑定可写流。
- unpipe():解绑可写流。
- on():监听事件
- data:当流中有数据可读时触发。
- end:当流中没有数据时触发。
- error:当流发生错误时触发。
- close:当流火底层资源关闭时触发。
const fs = require("fs");
fs.createReadStream("file.txt")
.on("data", chunk => {
console.log("读取数据:", chunk.toString());
});
暂停和恢复
const fs = require("fs");
const read = fs.createReadStream("file.txt");
read.setEncoding("utf8");
read.on("data", chunk => {
console.log("读取数据:", chunk.toString());
read.pause();
setTimeout(() => {
read.resume();
}, 1000);
});
read.on("close", chunk => {
console.log("读取完毕");
});
绑定可写流
const fs = require("fs");
const read = fs.createReadStream("file.txt");
read.pipe(fs.createWriteStream("file2.txt"));
可写流
创建可写流
// 使用stream模块
const stream = require("stream");
const writable=new stream.Writable({
write: function (chunk, encoding, next,) {
console.log(chunk.toString());
next();
}
}
);
// 使用fs模块
const fs = require("fs");
const writable = fs.createWriteStream("file.txt");
使用可写流
- wirte():写入数据。
- end():关闭流。
- destroy():销毁流。
- cork():将数据缓冲到内存。
- uncork():将内存的数据输出到目标处。
- on():监听事件
- finish:当所有数据已成功写入底层系统时触发。
- drain:当流的缓冲区已清空,可以继续写入数据时触发。
- error:当写入时发生错误触发。
- close:当流关闭时触发。
const fs = require("fs");
const writable = fs.createWriteStream("file.txt");
writable.write("Hello World");
关闭流
const fs = require("fs");
const writable = fs.createWriteStream("file.txt");
writable.write("Hello World");
// 结束写入
writable.end("写入完毕");
writable.on("close", () => {
console.log("写入结束");
});
缓冲数据
- cork():调用该方法后,所有写入的数据会被缓冲到内存中。
- uncork():调用该方法后,被缓冲的数据一次性写入底层系统。
const stream = require('stream');
const writable = new stream.Writable({
write: function (chunk, encoding, next) {
console.log(chunk.toString());
next();
}
});
writable.write('Hello!');
writable.write('World!');
writable.cork();
writable.write('ABC');
writable.write('EFG');
setTimeout(() => {
writable.uncork();
}, 2000);
可读可写流
可读可写流(双工流) Duplex 可以实现流的可读和可写功能,即同时实现 Readable 和 Writable。
要创建一个 Duplex 流,通常需要继承 stream.Duplex 类,并实现 _read 和 _write 方法。
const stream = require('stream');
class MyDuplex extends stream.Duplex {
constructor(options) {
super(options);
this.data = [];
}
// 从缓冲区读取数据
_read = function (size) {
const chunk = this.data.length > 0 ? this.data.shift() : null; // 从缓存读取数据
this.push(chunk); // 触发data事件
};
// 将数据写入缓冲区
_write = function (chunk, encoding, callback) {
this.data.push(chunk); // 写入操作
callback(); // 通知写入操作完成
};
}
const duplex = new MyDuplex();
// 监听data事件,负责接收数据
duplex.on('data', chunk => {
console.log("读取数据:", chunk.toString());
});
// 监听end事件,读取完毕后调用
duplex.on('end', () => {
console.log("读取完毕");
});
// 监听finish事件,写入完毕后调用
duplex.on('finish', () => {
console.log("写入完毕");
});
duplex.write("hello");
duplex.write("world");
duplex.end(); // 结束写入操作
// 读取数据: hello
// 读取数据: world
// 写入完毕
// 读取完毕
转换流
Transform
流是 Node.js 中的一种特殊类型的 Duplex
流,它用于在数据流经时对数据进行转换。Transform
流继承自 Duplex
流,但它专门用于处理数据的转换操作,例如加密、压缩、数据格式转换等。
const stream = require('stream');
class MyTransform extends stream.Transform {
constructor(options) {
super(options);
}
// 数据转换操作
_transform(chunk, encoding, callback) {
const result = chunk.toString().toUpperCase();
this.push(result);
callback();
}
}
const transform = new MyTransform();
transform.on("data", (chunk) => {
console.log("接收数据", chunk.toString());
});
transform.write("hello");
transform.write("world");
transform.end();
// 接收数据 HELLO
// 接收数据 WORLD