본문 바로가기

Web/Node.JS

[패스트캠퍼스 챌린지 21일차] NodeJS - Stream

Fast campus Logo

 

Fastcampus_Node.js 수강 목록

 

패스트캠퍼스 작심 30일 챌린지 21일차.

 


 

원래 오늘은 Nodejs에서 제공하는 Standard Library에 대해 작성하려 했지만,

Stream이 더 중요할 것 같아서 Stream에 대해 학습하였다.

 

강의를 통해서 Stream이 무엇인지, 종류가 어떻게 되는지,

그리고 실습을 통해 Stream을 어떻게 사용하는지 간략하게 배운 내용을 정리해보자.

 


 

먼저 Stream의 개요.

 

Stream은 Nodejs에서 가장 중요한 Datatype 중 하나로,

스트리밍이 가능한 리소스를 Handler에게 전송하는 기능이며

Data는 여러 개의 조각(Chunk)으로 분할하여 전송된다.

 

Stream은 용량이 큰 데이터를 처리하거나 비동기적으로만 얻을 수 있는 데이터를 처리할 때 유용한데,

대용량 파일을 압축하거나 읽고 쓸때, 그리고 Network Input(비동기)을 활용할 때 사용하면

효율적으로 처리할 수 있다.

 

const readFile = fs.createReadStream('file.txt');
readFile.on('data', data => {
    // TODO 데이터 처리
});
readFile.on('error', () => {
    // TODO Error 처리
});
readFile.on('end', () => {
    // TODO Stream 종료 후 처리
});

간단한 예시로 Stream을 통해 파일을 읽는 코드인데,

createReadStream을 통해 읽어온 파일을 각각의 핸들러가 처리하는 모습을 볼 수 있다.

이처럼 개발 목적에 맞게 핸들러를 통해 데이터를 처리할 수 있다.

 


 

다음으로 Stream의 종류.

 

Stream에는 Readable과 Writable, Duplex, Transform로 구분된다.

단어에서 쉽게 알 수 있듯이 Readable은 스트림을 통해 리소스를 읽는 역할을 수행하며,

위의 예시코드처럼 fs.createReadStream을 사용하거나 process.stdin을 통해 사용할 수 있다.

또한 서버가 HTTP 요청을 읽는 경우나 클라이언트가 HTTP 응답을 읽는 경우가 이에 해당한다.

 

그럼 당연히 Writable은 스트림을 통해 리소스를 작성하는 역할을 수행하며,

fs.createWriteStream이나 process.stdout을 통해 사용할 수 있다.

또한 Readable과 반대로 서버가 HTTP 응답을 쓰는 경우나 클라이언트가 HTTP 요청을 쓰는 경우가 이에 해당한다.

 

다음으로 Duplex!

Duplex는 스트림에 입력을 받을 수도, 출력을 보낼 수도 있으며,

TCP sockets, zlib stream, crypto streams가 여기에 해당한다.

 

마지막으로 Transform!

Transform은 입력받은 스트림을 변환해 새로운 스트림으로 만드는 역할을 하며,

zlib stream, crypto streams가 있다.

(zlib stream, crypto streams은 Duplex이면서 Transform이다.)

 


 

Stream 활용 실습

 

오늘의 마지막 학습은 바로 실습!

강의를 통해 파일을 작성하고, 작성한 파일을 읽는 예제 소스코드를 작성하여 Stream이 어떻게 사용되는지

간략히 알게 되었다.

 

[파일 쓰기]

const ws = fs.createWriteStream('./file.txt');

for (let i = 0; i < NUM_MB; i += 1) {
    // File Size를 키우기 위해 repeat 사용
    ws.write('a'.repeat(1024*1024);
}

Stream의 종류에서 알아본 createWriteStream을 통해 파일을 작성할 수 있도록 스트림을 생성하였다.

for문을 통해 a만 작성된 txt 파일을 생성하였다.

 

[파일 읽기]

const rs = fs.createReadStream('./file.txt', {
    encoding: 'utf-8',
    highWaterMark: 65536,
});

rs.on('data', (data) => {
    for (let i = 0; i < data.length; i += 1) {
        console.log(data[i]);
    }
});

rs.on('end', () => {
    console.log('end...');
});

그리고 작성한 파일을 읽어 정상적으로 작성되었는지 확인이 가능하다.

여기서 createReadStream을 생성할 때 데이터의 인코딩을 설정할 수 있고,

highWaterMark를 통해 버퍼 사이즈를 조절할 수 있다.

(highWaterMark는 작성하지 않으면 65,536이 Default로 설정된다.)

 

그리고 읽은 파일의 데이터를 처리하기 위해 on('data') 함수를 활용하고,

파일을 다 읽은 경우, 즉 스트림이 끝나는 시점에서 on('end') 함수를 통해 기능을 구현하면 된다.

 


 

[오늘의 학습통계]

패스트캠퍼스 작심 30일 챌린지 21일차 학습통계


- 패스트캠퍼스 URL : https://bit.ly/37BpXiC

* 본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.