> 웹 프론트엔드 > JS 튜토리얼 > Node.js 스트림 이해: 무엇을, 왜, 어떻게 사용하는가

Node.js 스트림 이해: 무엇을, 왜, 어떻게 사용하는가

Mary-Kate Olsen
풀어 주다: 2024-09-21 06:24:08
원래의
365명이 탐색했습니다.

Understanding Node.js Streams: What, Why, and How to Use Them

Node.js Streams는 대용량 데이터를 효율적으로 처리하는 데 필수적인 기능입니다. 기존 입출력 메커니즘과 달리 스트림을 사용하면 전체 데이터를 메모리에 로드하는 대신 데이터를 청크로 처리할 수 있으므로 대용량 파일이나 실시간 데이터를 처리하는 데 적합합니다. 이 기사에서는 Node.js Streams가 무엇인지, 왜 유용한지, 어떻게 구현하는지, 그리고 자세한 예시와 사용 사례를 통해 다양한 유형의 스트림에 대해 자세히 알아볼 것입니다.

Node.js 스트림이란 무엇입니까?

간단히 말하면 스트림은 시간이 지남에 따라 한 지점에서 다른 지점으로 이동되는 일련의 데이터입니다. 데이터가 한꺼번에 흐르지 않고 하나씩 흐르는 컨베이어 벨트라고 생각하시면 됩니다.

Node.js Streams도 비슷하게 작동합니다. 데이터를 한 번에 모두 읽지 않고 여러 단위로 읽고 쓸 수 있어 메모리 효율성이 높습니다.

Node.js의 스트림은 EventEmitter 위에 구축되어 이벤트 중심으로 만들어집니다. 몇 가지 중요한 이벤트는 다음과 같습니다.

  • data: 데이터를 사용할 수 있을 때 내보냅니다.
  • end: 더 이상 사용할 수 있는 데이터가 없을 때 발생합니다.
  • error: 읽거나 쓰는 동안 오류가 발생할 때 발생합니다.

스트림을 사용하는 이유는 무엇입니까?

스트림은 I/O 처리에 있어 fs.readFile() 또는 fs.writeFile()과 같은 기존 방법에 비해 몇 가지 장점을 제공합니다.

  1. 메모리 효율성: 데이터가 단위로 처리되므로 대용량 파일을 많은 메모리 소모 없이 처리할 수 있습니다.
  2. 성능: 스트림은 비차단 I/O를 제공합니다. 전체 작업이 완료될 때까지 기다리지 않고 데이터를 하나씩 읽거나 쓸 수 있으므로 프로그램의 응답성이 향상됩니다.
  3. 실시간 데이터 처리: 스트림을 사용하면 라이브 비디오/오디오 또는 API의 대규모 데이터 세트와 같은 실시간 데이터를 처리할 수 있습니다.

Node.js의 스트림 유형

Node.js에는 네 가지 유형의 스트림이 있습니다.

  1. 읽기 가능한 스트림: 데이터를 읽는 데 사용됩니다.
  2. 쓰기 가능한 스트림: 데이터 쓰기용.
  3. 이중 스트림: 데이터를 동시에 읽고 쓸 수 있는 스트림
  4. 변환 스트림: 출력이 입력의 수정된 버전인 이중 스트림 유형(예: 데이터 압축).

각 유형을 예시로 살펴보겠습니다.

1. 읽기 가능한 스트림

읽기 가능한 스트림은 데이터를 청크 단위로 읽는 데 사용됩니다. 예를 들어, 대용량 파일을 읽을 때 읽기 가능한 스트림을 사용하면 전체 파일을 로드하는 대신 작은 데이터 청크를 메모리로 읽을 수 있습니다.

예: 읽기 가능한 스트림을 사용하여 파일 읽기

const fs = require('fs');

// Create a readable stream
const readableStream = fs.createReadStream('largefile.txt', { encoding: 'utf8' });

// Listen for data events and process chunks
readableStream.on('data', (chunk) => {
  console.log('Chunk received:', chunk);
});

// Listen for the end event when no more data is available
readableStream.on('end', () => {
  console.log('No more data.');
});

// Handle error event
readableStream.on('error', (err) => {
  console.error('Error reading the file:', err);
});
로그인 후 복사

설명:

  • fs.createReadStream()은 파일을 청크로 읽기 위한 스트림을 생성합니다.
  • 청크가 준비될 때마다 데이터 이벤트가 발생하고, 더 이상 읽을 데이터가 없으면 종료 이벤트가 발생합니다.

2. 쓰기 가능한 스트림

쓰기 가능한 스트림은 데이터를 청크 단위로 쓰는 데 사용됩니다. 모든 데이터를 한 번에 쓰는 대신 파일이나 쓰기 가능한 다른 대상으로 스트리밍할 수 있습니다.

예: 쓰기 가능한 스트림을 사용하여 데이터 쓰기

const fs = require('fs');

// Create a writable stream
const writableStream = fs.createWriteStream('output.txt');

// Write chunks to the writable stream
writableStream.write('Hello, World!\n');
writableStream.write('Streaming data...\n');

// End the stream (important to avoid hanging the process)
writableStream.end('Done writing.\n');

// Listen for the finish event
writableStream.on('finish', () => {
  console.log('Data has been written to output.txt');
});

// Handle error event
writableStream.on('error', (err) => {
  console.error('Error writing to the file:', err);
});
로그인 후 복사

설명:

  • fs.createWriteStream()은 쓰기 가능한 스트림을 생성합니다.
  • write() 메서드를 사용하여 데이터가 스트림에 기록됩니다.
  • 모든 데이터가 기록되면 종료 이벤트가 발생하며 end() 메소드는 스트림의 끝을 표시합니다.

3. 이중 스트림

이중 스트림은 데이터를 읽고 쓸 수 있습니다. 이중 스트림의 일반적인 예로는 데이터를 동시에 보내고 받을 수 있는 네트워크 소켓이 있습니다.

예: 이중 스트림

const { Duplex } = require('stream');

const duplexStream = new Duplex({
  write(chunk, encoding, callback) {
    console.log(`Writing: ${chunk.toString()}`);
    callback();
  },
  read(size) {
    this.push('More data');
    this.push(null);  // End the stream
  }
});

// Write to the duplex stream
duplexStream.write('Hello Duplex!\n');

// Read from the duplex stream
duplexStream.on('data', (chunk) => {
  console.log(`Read: ${chunk}`);
});
로그인 후 복사

설명:

  • 쓰기에는 쓰기 방식, 읽기에는 읽기 방식을 정의합니다.
  • 이중 스트림은 읽기와 쓰기를 동시에 처리할 수 있습니다.

4. 스트림 변환

변환 스트림은 스트림을 통과할 때 데이터를 수정합니다. 예를 들어 변환 스트림은 데이터를 압축, 암호화 또는 조작할 수 있습니다.

예: 변환 스트림(대문자 텍스트)

const { Transform } = require('stream');

// Create a transform stream that converts data to uppercase
const transformStream = new Transform({
  transform(chunk, encoding, callback) {
    this.push(chunk.toString().toUpperCase());
    callback();
  }
});

// Pipe input to transform stream and then output the result
process.stdin.pipe(transformStream).pipe(process.stdout);
로그인 후 복사

설명:

  • stdin에서 입력된 데이터는 변환 메소드에 의해 대문자로 변환된 후 stdout으로 출력됩니다.

배관 스트림

Node.js 스트림의 주요 기능 중 하나는 파이프되는 기능입니다. 파이핑을 사용하면 스트림을 서로 연결하여 한 스트림의 출력을 다른 스트림의 입력으로 전달할 수 있습니다.

예: 읽기 가능한 스트림을 쓰기 가능한 스트림으로 파이핑

const fs = require('fs');

// Create a readable stream for the input file
const readableStream = fs.createReadStream('input.txt');

// Create a writable stream for the output file
const writableStream = fs.createWriteStream('output.txt');

// Pipe the readable stream into the writable stream
readableStream.pipe(writableStream);

// Handle errors
readableStream.on('error', (err) => console.error('Read error:', err));
writableStream.on('error', (err) => console.error('Write error:', err));
로그인 후 복사

설명:

  • pipe() 메소드는 읽기 가능한 스트림을 쓰기 가능한 스트림에 연결하여 input.txt에서 output.txt로 직접 데이터 청크를 보냅니다.

Node.js 스트림의 실제 사용 사례

  1. 대용량 파일 읽기 및 쓰기: 전체 파일을 메모리로 읽는 대신 스트림을 사용하면 파일을 작은 단위로 처리할 수 있습니다.
  2. 실시간 데이터 처리: 스트림은 오디오/비디오 처리, 채팅 애플리케이션 또는 라이브 데이터 피드와 같은 실시간 애플리케이션에 이상적입니다.
  3. HTTP 요청/응답: Node.js의 HTTP 요청과 응답은 스트림이므로 들어오는 데이터를 쉽게 처리하거나 점진적으로 데이터를 보낼 수 있습니다.

결론

Node.js 스트림은 데이터를 청크로 작업하여 I/O 작업을 처리하는 강력하고 효율적인 방법을 제공합니다. 대용량 파일을 읽거나, 소스 간에 데이터를 파이핑하거나, 즉시 데이터를 변환하는 경우 스트림은 메모리 효율적이고 성능이 뛰어난 솔루션을 제공합니다. 애플리케이션에서 읽기 가능, 쓰기 가능, 이중 및 변환 스트림을 활용하는 방법을 이해하면 애플리케이션의 성능과 확장성을 크게 향상시킬 수 있습니다.

위 내용은 Node.js 스트림 이해: 무엇을, 왜, 어떻게 사용하는가의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿