Files
Knowledge/0 编程/node/nodejs 中的流式输入输出,看这篇就够了.md
T

148 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
流式输入(Stream Input)是一种数据处理方式,其中数据不是一次性全部加载到内存中,而是以连续的数据流形式逐块处理。这种方式特别适用于处理大量数据或实时数据,因为它可以减少内存占用并提高处理效率。
流式输出(Stream Output)是一种数据处理方式,其中数据不是一次性全部生成并发送,而是以连续的数据流形式逐块生成并发送。这种方式特别适用于处理大量数据或实时数据,因为它可以减少内存占用并提高处理效率。
关键概念和应用场景:
## 关键概念
1. **数据流**:
- 数据流是指数据以连续的方式传输,而不是一次性传输完整个数据集。
- 数据流可以是字节流、字符流、文件流等。
1. **逐块处理**:
- 流式输入通常以固定大小的块(例如,几KB或几MB)读取数据,并在读取后立即处理这些块。
- 这种方式允许程序在数据到达时就开始处理,而不需要等待所有数据都加载完毕。
1. **低延迟**:
- 流式输入可以实现实时或近实时的数据处理,因为数据可以在到达时立即被处理。
1. **资源高效**:
- 由于数据是逐块处理的,流式输入可以显著减少内存占用,适用于处理大规模数据集。
## 应用场景
1. **文件读写**:
- 处理大文件时,可以使用流式输入逐块读取文件内容,避免一次性加载整个文件导致内存溢出。
- 例如,使用 Node.js 的 fs.createReadStream 方法读取大文件。
1. **网络通信**:
- 在网络编程中,数据通常以流的形式传输,例如 HTTP 请求和响应。
- 例如,使用 Node.js 的 http 模块处理 HTTP 请求和响应。
1. **实时数据处理**:
- 处理实时数据流,如传感器数据、日志数据等。
- 例如,使用 Apache Kafka 或 AWS Kinesis 处理实时数据流。
1. **多媒体处理**:
- 处理音频、视频等多媒体数据时,通常使用流式输入逐块读取和处理数据。
- 例如,使用 FFmpeg 处理视频流。
## 示例
## Node.js 中的流式文件读取
```text
const fs = require('fs');
// 创建一个可读流
const readStream = fs.createReadStream('large-file.txt', { highWaterMark: 1024 * 1024 }); // 每次读取1MB
// 监听数据事件
readStream.on('data', (chunk) => {
console.log(`Received ${chunk.length} bytes of data.`);
// 处理数据块
});
// 监听结束事件
readStream.on('end', () => {
console.log('No more data to read.');
});
// 监听错误事件
readStream.on('error', (err) => {
console.error('Error reading file:', err);
});
```
## 使用 Express 处理 HTTP 请求流
```text
const express = require('express');
const app = express();
app.get('/stream', (req, res) => {
// 创建一个可读流
const readStream = fs.createReadStream('large-file.txt');
// 将可读流管道到响应对象
readStream.pipe(res);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
```
## Node.js 中的流式文件写入
```text
const fs = require('fs');
// 创建一个可写流
const writeStream = fs.createWriteStream('large-file.txt', { highWaterMark: 1024 * 1024 }); // 每次写入1MB
// 生成数据并写入流
for (let i = 0; i < 1000; i++) {
const data = `This is line ${i}\n`;
writeStream.write(data, (err) => {
if (err) {
console.error('Error writing to file:', err);
}
});
}
// 结束写入
writeStream.end(() => {
console.log('File has been written successfully.');
});
// 监听错误事件
writeStream.on('error', (err) => {
console.error('Error writing to file:', err);
});
```
## 使用 Express 发送 HTTP 响应流
```text
const express = require('express');
const fs = require('fs');
const app = express();
app.get('/stream', (req, res) => {
// 创建一个可读流
const readStream = fs.createReadStream('large-file.txt');
// 将可读流管道到响应对象
readStream.pipe(res);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
```
## 总结
流式输入/出是一种高效的数据处理方式,特别适用于处理大量数据或实时数据。通过逐块处理数据,它可以减少内存占用并提高处理效率。