"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 스트림: Node.js

스트림: Node.js

2024-11-01에 게시됨
검색:362

Streams: Node.js

Node.js의 스트림에 대한 전체 가이드

Node.js의 스트림은 지속적인 방식으로 데이터 읽기 및 쓰기를 처리하는 강력한 방법입니다. 이를 통해 특히 대량의 정보나 I/O 작업을 처리할 때 데이터를 효율적으로 처리할 수 있습니다. 이 가이드에서는 Node.js에서 스트림이 작동하는 방식을 이해하는 데 도움이 되는 스트림 유형, 사용 방법 및 실제 예를 다룹니다.

스트림이란 무엇입니까?

스트림은 소스에서 데이터를 읽거나 연속적인 방식으로 대상에 데이터를 쓸 수 있는 개체입니다. 전체 파일이나 버퍼를 한 번에 읽거나 쓰는 대신 데이터를 하나씩 처리하는 데 이상적입니다. 이는 메모리 사용량을 크게 줄일 수 있으므로 대규모 데이터 세트로 작업할 때 특히 유용합니다.

주요 개념

  • 흐름 모드: 데이터가 소스에서 대상으로 자동으로 흐릅니다.
  • 일시 중지 모드: 소스에서 데이터를 수동으로 읽어야 합니다.
  • 읽기 가능한 스트림: 데이터를 읽을 수 있는 스트림.
  • 쓰기 가능한 스트림: 데이터를 쓸 수 있는 스트림.
  • 이중 스트림: 데이터를 읽고 쓸 수 있는 스트림.
  • 변환 스트림: 데이터를 읽거나 쓸 때 데이터를 수정하거나 변환하는 스트림입니다.

스트림 유형

  1. 읽기 가능한 스트림: 이 스트림을 사용하면 데이터를 읽을 수 있습니다. 예에는 fs.createReadStream() 및 http.IncomingMessage.

  2. 가 포함됩니다.
  3. 쓰기 가능한 스트림: 이 스트림을 사용하면 데이터를 쓸 수 있습니다. 예에는 fs.createWriteStream() 및 http.ServerResponse.

  4. 가 포함됩니다.
  5. 이중 스트림: 이 스트림은 데이터를 읽고 쓸 수 있습니다. 예에는 TCP 소켓 및 net.Duplex.

  6. 가 포함됩니다.
  7. 변형 스트림: 데이터를 읽거나 쓰는 동안 데이터를 수정할 수 있는 이중 스트림 유형입니다. 예에는 압축을 위한 zlib.createGzip()이 포함됩니다.

읽기 가능한 스트림 생성

내장된 fs 모듈을 사용하여 파일을 읽거나 stream.Readable을 사용하여 읽기 가능한 사용자 정의 스트림을 생성하는 읽기 가능한 스트림을 생성할 수 있습니다.

예: 읽기 가능한 스트림으로 파일 읽기

const fs = require('fs');

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

// Handling the 'data' event
readableStream.on('data', (chunk) => {
    console.log('New chunk received:', chunk);
});

// Handling the 'end' event
readableStream.on('end', () => {
    console.log('No more data to read.');
});

예: 사용자 정의 읽기 가능 스트림

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

class MyReadableStream extends Readable {
    constructor(options) {
        super(options);
        this.current = 0;
    }

    _read(size) {
        if (this.current  {
    console.log('Received:', chunk.toString());
});

쓰기 가능한 스트림 생성

fs 모듈을 사용하거나 stream.Writable 클래스를 확장하여 쓰기 가능한 스트림을 생성할 수 있습니다.

예: 쓰기 가능한 스트림이 있는 파일에 쓰기

const fs = require('fs');

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

// Write data to the stream
writableStream.write('Hello, World!\n');
writableStream.write('Writing to a file using streams.\n');

// End the stream
writableStream.end(() => {
    console.log('Finished writing to file.');
});

예: 사용자 정의 쓰기 가능 스트림

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

class MyWritableStream extends Writable {
    _write(chunk, encoding, callback) {
        console.log('Writing:', chunk.toString());
        callback(); // Call when done
    }
}

const myWritableStream = new MyWritableStream();
myWritableStream.write('Hello, World!\n');
myWritableStream.write('Writing to custom writable stream.\n');
myWritableStream.end();

이중 스트림 사용

이중 스트림은 동시에 데이터를 읽고 쓸 수 있습니다. 일반적인 사용 사례는 TCP 소켓입니다.

예: 이중 스트림 생성

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

class MyDuplexStream extends Duplex {
    _read(size) {
        this.push('Data from duplex stream\n');
        this.push(null); // No more data
    }

    _write(chunk, encoding, callback) {
        console.log('Received:', chunk.toString());
        callback();
    }
}

const myDuplexStream = new MyDuplexStream();
myDuplexStream.on('data', (chunk) => {
    console.log('Reading:', chunk.toString());
});

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

변환 스트림 사용

변환 스트림은 스트림을 통해 흐르는 데이터를 수정하는 데 유용합니다. 예를 들어 변환 스트림을 사용하여 데이터를 압축할 수 있습니다.

예: 변환 스트림 생성

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

class MyTransformStream extends Transform {
    _transform(chunk, encoding, callback) {
        const upperChunk = chunk.toString().toUpperCase();
        this.push(upperChunk);
        callback();
    }
}

const myTransformStream = new MyTransformStream();
myTransformStream.on('data', (chunk) => {
    console.log('Transformed:', chunk.toString());
});

// Pipe data through the transform stream
process.stdin.pipe(myTransformStream).pipe(process.stdout);

배관 스트림

스트림의 강력한 기능 중 하나는 스트림을 함께 연결하는 기능입니다. 파이핑을 사용하면 읽기 가능한 스트림을 쓰기 가능한 스트림에 연결할 수 있으므로 데이터 전송이 쉬워집니다.

예: 배관 스트림

const fs = require('fs');

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

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

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

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

Node.js의 스트림 이벤트

1. 읽기 가능한 스트림 이벤트

읽기 가능한 스트림은 데이터 흐름을 관리하는 데 도움이 되는 몇 가지 중요한 이벤트를 내보냅니다.

  • 데이터: 데이터 덩어리를 읽을 수 있을 때 발생합니다.
  • end: 더 이상 읽을 데이터가 없을 때 발생합니다.
  • 오류: 읽는 동안 오류가 발생하면 발생합니다.
  • close: 스트림과 기본 리소스(예: 파일 설명자)가 닫힐 때 발생합니다.

예: 읽기 가능한 스트림 이벤트

const fs = require('fs');

const readableStream = fs.createReadStream('example.txt');

readableStream.on('data', (chunk) => {
    console.log('Received chunk:', chunk.toString());
});

readableStream.on('end', () => {
    console.log('No more data to read.');
});

readableStream.on('error', (err) => {
    console.error('Error occurred:', err);
});

readableStream.on('close', () => {
    console.log('Stream closed.');
});

2. 쓰기 가능한 스트림 이벤트

쓰기 가능한 스트림은 다음과 같은 여러 이벤트도 내보냅니다.

  • drain: 스트림이 가득 찬 후 더 많은 데이터를 수용할 준비가 되면 방출됩니다.
  • finish: 모든 데이터가 스트림에 기록되고 end() 메서드가 호출되면 발생합니다.
  • 오류: 작성 중 오류가 발생하면 발생합니다.
  • close: 스트림과 기본 리소스가 닫힐 때 발생합니다.

예: 쓰기 가능한 스트림 이벤트

const fs = require('fs');

const writableStream = fs.createWriteStream('output.txt');

writableStream.on('finish', () => {
    console.log('All data has been written to output.txt');
});

writableStream.on('error', (err) => {
    console.error('Error occurred:', err);
});

// Writing data
writableStream.write('Hello, World!\n');
writableStream.write('Writing to a file using streams.\n');
writableStream.end(); // Call end to finish the writing process

3. 스트림 이벤트 변환

변환 스트림은 읽기 가능하고 쓰기 가능한 스트림 모두에서 이벤트를 상속하며 다음을 내보냅니다.

  • 데이터: 변환된 청크를 읽을 수 있을 때 방출됩니다.
  • end: 변환할 데이터가 더 이상 없을 때 발생합니다.
  • 오류: 변환 중 오류가 발생하면 발생합니다.
  • finish: 모든 데이터가 처리되고 기록되면 발생합니다.

예: 스트림 이벤트 변환

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

class MyTransformStream extends Transform {
    _transform(chunk, encoding, callback) {
        const upperChunk = chunk.toString().toUpperCase();
        this.push(upperChunk);
        callback();
    }
}

const myTransformStream = new MyTransformStream();

myTransformStream.on('data', (chunk) => {
    console.log('Transformed chunk:', chunk.toString());
});

myTransformStream.on('end', () => {
    console.log('No more data to transform.');
});

myTransformStream.on('error', (err) => {
    console.error('Error occurred:', err);
});

// Write data to the transform stream
myTransformStream.write('Hello, World!\n');
myTransformStream.write('Transforming this text.\n');
myTransformStream.end(); // End the stream

이벤트 요약

  • 읽기 가능한 스트림: 데이터, 종료, 오류, 닫기
  • 쓰기 가능한 스트림: 배수, 완료, 오류, 닫기
  • 스트림 변환: 읽기 및 쓰기 가능한 스트림 모두에서 데이터, 종료, 오류, 종료를 상속합니다.

결론

Node.js의 스트림은 데이터를 지속적으로 처리하는 강력하고 효율적인 방법을 제공합니다. 이를 통해 데이터를 하나씩 읽고 쓸 수 있으므로 I/O 작업 및 대규모 데이터 세트 작업에 특히 유용합니다. 다양한 유형의 스트림을 생성하고 사용하는 방법과 이벤트를 처리하는 방법을 이해하면 Node.js에서 보다 효율적이고 확장 가능한 애플리케이션을 구축하는 데 도움이 됩니다.

읽기 가능, 쓰기 가능, 이중 또는 변환 스트림을 생성하는 경우 스트림 API의 유연성을 통해 애플리케이션 요구 사항에 가장 적합한 방식으로 데이터 처리를 처리할 수 있습니다.

릴리스 선언문 이 글은 https://dev.to/harshm03/streams-nodejs-2j32?1에서 복제되었습니다. 침해 내용이 있는 경우, [email protected]으로 연락하여 삭제하시기 바랍니다.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3