跳转到内容

JavaScript Node.js流

来自代码酷

Node.js流(Streams)是Node.js核心模块中处理流式数据的抽象接口,用于高效处理大量数据(如文件、网络通信等)。流将数据分割成小块(chunks)并按顺序处理,避免内存溢出,适用于I/O密集型操作。

流的基本类型[编辑 | 编辑源代码]

Node.js提供四种基础流类型:

  • 可读流(Readable):数据来源(如文件读取、HTTP请求)。
  • 可写流(Writable):数据目标(如文件写入、HTTP响应)。
  • 双工流(Duplex):既可读又可写(如TCP套接字)。
  • 转换流(Transform):在读写过程中修改数据(如压缩流)。

flowchart LR A[可读流] -->|读取数据| B[可写流] C[双工流] -->|双向通信| D[转换流]

流的工作模式[编辑 | 编辑源代码]

流有两种工作模式:

  1. 流动模式(Flowing):数据自动通过事件推送。
  2. 暂停模式(Paused):需手动调用read()读取数据。

示例:可读流[编辑 | 编辑源代码]

  
const fs = require('fs');  
const readableStream = fs.createReadStream('input.txt');  

// 流动模式  
readableStream.on('data', (chunk) => {  
    console.log(`接收到 ${chunk.length} 字节数据`);  
});  

readableStream.on('end', () => {  
    console.log('数据读取完成');  
});

输出(假设文件内容为"Hello Node.js"):

  
接收到 13 字节数据  
数据读取完成  

管道(Pipe)[编辑 | 编辑源代码]

管道用于将可读流的数据直接导向可写流,简化代码:

  
const fs = require('fs');  
const zlib = require('zlib');  

// 文件压缩示例  
fs.createReadStream('input.txt')  
    .pipe(zlib.createGzip())  
    .pipe(fs.createWriteStream('input.txt.gz'));

实际应用场景[编辑 | 编辑源代码]

  • 大文件处理:分块读取/写入避免内存不足。
  • 实时数据传输:视频流、日志处理。
  • 数据转换:加密/压缩流。

案例:HTTP服务器流[编辑 | 编辑源代码]

  
const http = require('http');  
const fs = require('fs');  

http.createServer((req, res) => {  
    fs.createReadStream('largefile.pdf').pipe(res); // 高效发送大文件  
}).listen(3000);

错误处理[编辑 | 编辑源代码]

流通过error事件处理异常:

  
readableStream.on('error', (err) => {  
    console.error('流发生错误:', err);  
});

性能优化[编辑 | 编辑源代码]

  • 使用highWaterMark调整缓冲区大小。
  • 避免“背压”(Backpressure)问题,监听drain事件控制写入速度。

背压处理示例[编辑 | 编辑源代码]

  
const writableStream = fs.createWriteStream('output.txt');  
readableStream.on('data', (chunk) => {  
    if (!writableStream.write(chunk)) {  
        readableStream.pause(); // 暂停读取直到可写流准备好  
    }  
});  

writableStream.on('drain', () => {  
    readableStream.resume(); // 恢复读取  
});

总结[编辑 | 编辑源代码]

Node.js流通过分块处理和管道机制优化I/O性能,适用于大规模数据场景。掌握流的核心类型、事件和错误处理是构建高效应用的关键。

模板:Stub