Node.js入门笔记6
- [Node.js---fs 流(Streams)与管道(Pipe)](#Node.js---fs 流(Streams)与管道(Pipe))
- 一、流(Streams)与管道(Pipe)
-
- 1.fs.createReadStream():创建可读流,逐块读取文件。逐块读取文件内容,适用于大文件或需要实时处理的场景(如视频流、日志分析)。
- [2. fs.createWriteStream():创建可写流,逐块写入文件。逐块写入文件内容,适用于逐步生成或接收数据的场景(如下载文件、日志记录)](#2. fs.createWriteStream():创建可写流,逐块写入文件。逐块写入文件内容,适用于逐步生成或接收数据的场景(如下载文件、日志记录))
- [3.pipe() 将可读流直接传输到可写流。](#3.pipe() 将可读流直接传输到可写流。)
Node.js---fs 流(Streams)与管道(Pipe)
一、流(Streams)与管道(Pipe)
1.fs.createReadStream():创建可读流,逐块读取文件。逐块读取文件内容,适用于大文件或需要实时处理的场景(如视频流、日志分析)。
语法格式:
bash
const readStream = fs.createReadStream(path, {
// 可选参数
flags: 'r', // 文件打开模式
encoding: null, // 编码格式(默认 Buffer)
fd: null, // 文件描述符(如果提供,则忽略 path)
mode: 0o666, // 文件权限(默认 0o666)
autoClose: true, // 是否自动关闭文件描述符
emitClose: true, // 是否触发 'close' 事件
start: 0, // 读取起始位置(字节)
end: Infinity, // 读取结束位置(字节)
highWaterMark: 64 * 1024 // 每次读取的缓冲区大小(字节)
});
参数解读:
path: 必选参数,文件路径
options: 可选参数,可指定编码格式、文件打开模式等
javascript
const fs = require('fs');
// 读取文件的中间部分(字节 100 到 200)
const readStream = fs.createReadStream('data.bin', {
encoding: 'utf8', // 指定文本编码
start: 100, // 从第 100 字节开始
end: 200, // 到第 200 字节结束
highWaterMark: 1024 // 每次读取 1KB
});
readStream.on('data', (chunk) => {
console.log('收到数据块:', chunk);
});
写完代码后,需要在terminal控制台输入指令:node 【 js文件的路径】
bash
node C:\Users\Administrator\Desktop\learning\createReadStream.js
2. fs.createWriteStream():创建可写流,逐块写入文件。逐块写入文件内容,适用于逐步生成或接收数据的场景(如下载文件、日志记录)
语法格式
bash
const writeStream = fs.createWriteStream(path, {
// 可选参数
flags: 'w', // 文件打开模式
encoding: 'utf8', // 编码格式(默认 utf8)
fd: null, // 文件描述符(如果提供,则忽略 path)
mode: 0o666, // 文件权限(默认 0o666)
autoClose: true, // 是否自动关闭文件描述符
emitClose: true, // 是否触发 'close' 事件
start: 0 // 写入起始位置(字节)
});
参数解读:
path: 必选参数,文件路径
options: 可选参数,可指定编码格式、文件打开模式等
javascript
const fs = require('fs');
// 以追加模式写入日志
const writeStream = fs.createWriteStream('app.log', {
flags: 'a', // 追加模式(不覆盖原有内容)
encoding: 'utf8', // 文本编码
});
writeStream.write('用户登录\n');
writeStream.write('操作记录\n');
writeStream.end('日志结束\n'); // 结束写入
写完代码后,需要在terminal控制台输入指令:node 【 js文件的路径】
bash
node C:\Users\Administrator\Desktop\access.js
3.pipe() 将可读流直接传输到可写流。
特点 :
1.自动处理数据流动。
2.自动控制背压(Backpressure,即读写速度不一致的问题)。
3.错误不会自动传递,需手动监听错误事件。
核心原理
1.数据流动:
当可读流有数据时,自动触发 data 事件,将数据块(chunk)写入可写流。
当可写流的缓冲区满时,暂停可读流(调用 readableStream.pause())。
当可写流缓冲区清空时,恢复可读流(调用 readableStream.resume())。
2.背压控制:
如果可写流处理速度 < 可读流生产速度,pipe() 会自动暂停可读流,避免内存溢出。
语法格式:
javascript
readableStream.pipe(writableStream[, options]);
参数解读:
writableStream :默认情况下自动调用 writableStream.end(),但可以通过将 end 选项设置为 false 来禁用此行为。
options :是一个可选的对象,可以包含 end 和其他选项。
默认行为:
javascript
// 1.导入fs模块
const fs = require('fs');
// 创建可读流和可写流
const readStream = fs.createReadStream('input.txt');
const writeStream = fs.createWriteStream('output.txt');
// 传输数据,自动结束可写流
readStream.pipe(writeStream);
// 等同于 readStream.pipe(writeStream, { end: true });
writeStream.on('finish', () => {
console.log('数据写入完成,可写流已自动关闭!');
});
写完代码后,需要在terminal控制台输入指令:node 【 js文件的路径】
bash
node C:\Users\Administrator\Desktop\learning\pipe.js
手动结束可写流:
javascript
const fs = require('fs');
const writeStream = fs.createWriteStream('combined.log');
// 第一个可读流写入
fs.createReadStream('log1.txt')
.pipe(writeStream, { end: false }) // 不自动结束
.on('end', () => {
// 继续追加第二个可读流
fs.createReadStream('log2.txt')
.pipe(writeStream, { end: false })
.on('end', () => {
// 手动结束可写流
writeStream.end('--- 日志合并完成 ---\n');
});
});
写完代码后,需要在terminal控制台输入指令:node 【 js文件的路径】
bash
node C:\Users\Administrator\Desktop\learning\pipe.js