MST

星途 面试题库

面试题:Node.js HTTP模块中的流处理与性能优化

在Node.js使用HTTP模块处理大文件传输时,怎样利用流(Stream)来优化性能?请阐述流的不同类型(可读流、可写流等)在这种场景下的协作方式,并给出一个简单的代码示例展示如何高效地实现文件上传或下载功能。
22.7万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

利用流优化大文件传输性能

在Node.js使用HTTP模块处理大文件传输时,流(Stream)通过以下方式优化性能:

  1. 避免内存占用:流不会一次性将整个文件读入内存,而是逐块处理数据,这在处理大文件时极大地减少了内存占用。
  2. 提高传输效率:数据可以在产生和消费的同时进行传输,而不需要等待整个文件被完全读取或生成,从而提高了传输效率。

流的不同类型及协作方式

  1. 可读流(Readable Stream):用于从源(如文件系统中的文件)读取数据。在大文件传输中,它从文件逐块读取数据。
  2. 可写流(Writable Stream):用于将数据写入目标(如HTTP响应或者另一个文件)。在大文件传输中,它将可读流读取的数据逐块写入到目标位置。
  3. 管道(pipe):通过pipe方法,可以将可读流和可写流连接起来,实现数据的自动流动。可读流一旦有数据可读,就会自动将数据推送到可写流,这简化了数据传输的过程并且高效地管理了背压(backpressure)。

代码示例 - 文件下载

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

const server = http.createServer((req, res) => {
    const filePath = 'largeFile.txt'; // 假设要下载的大文件
    const readStream = fs.createReadStream(filePath);

    // 设置响应头
    res.setHeader('Content-Disposition', 'attachment; filename="largeFile.txt"');
    res.setHeader('Content-Type', 'text/plain');

    // 使用管道将可读流连接到可写流(HTTP响应)
    readStream.pipe(res);

    // 处理错误
    readStream.on('error', (err) => {
        res.statusCode = 500;
        res.end('Error occurred while reading the file');
    });
});

const port = 3000;
server.listen(port, () => {
    console.log(`Server running on port ${port}`);
});

代码示例 - 文件上传

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

const server = http.createServer((req, res) => {
    if (req.method === 'POST') {
        const writeStream = fs.createWriteStream('uploadedFile.txt');

        // 将HTTP请求(可读流)的数据管道到文件写入流(可写流)
        req.pipe(writeStream);

        writeStream.on('finish', () => {
            res.end('File uploaded successfully');
        });

        // 处理错误
        req.on('error', (err) => {
            res.statusCode = 500;
            res.end('Error occurred while uploading the file');
        });

        writeStream.on('error', (err) => {
            res.statusCode = 500;
            res.end('Error occurred while writing the file');
        });
    } else {
        res.end('Only POST method is allowed for file upload');
    }
});

const port = 3000;
server.listen(port, () => {
    console.log(`Server running on port ${port}`);
});