본문 바로가기

공부/Node.js

[Node.js] 버퍼와 스트림

이전에 배웠던 언어들에서 주구장창 사용해왔지만 아직 정확하게 이해는 가지 않는 버퍼와 스트림에 대해서 확실하게 짚고 넘어갈겸 포스팅을 한다.

 

버퍼

 

 

그림으로 그리면 대충 이런 느낌인데 노드에서는 데이터를 전송할 때 버퍼에 저장해서 이 버퍼를 우리들이 다뤄서 데이터를 전송하는 방식이라고 한다.

 

const buffer = Buffer.from('저를 버퍼로 바꿔보세요');
console.log('from()', buffer);
console.log('length:', buffer.length);
console.log('toString():', buffer.toString());

const array = [Buffer.from('띄엄 '), Buffer.from('띄엄 '), Buffer.from('띄어쓰기')];
const buffer2 = Buffer.concat(array);
console.log('concat():', buffer2.toString());

const buffer3 = Buffer.alloc(5);
console.log('alloc():', buffer3);

 

버퍼의 다양한 기능을 이용한 함수인데 length나 toString()과 같이 일반적으로 많이 쓰이는 함수들 보다는

 

concat : 배열안의 버퍼들을 하나로 합친다.

alloc : 빈 버퍼를 생성한다.

 

이렇게 2개를 보는게 더 중요할 것 같다. 실제로 실행을 시켜보면

 

 

concat을 보면 실제로 array에 따로 담겨져있는 Buffer들이 buffer2에서 하나로 합쳐진 것을 볼 수 있다.

alloc은 alloc(5)로 사용되었으며 5개의 빈 Buffer가 생긴것을 볼 수 있다.

 

이렇게 버퍼는 유용하지만 단점이 있다. 바로 메모리 소비에 관한 것이다.

 

100MB 용량의 파일을 읽을 때는 메모리 100MB의 버퍼를 만들어야하고 이 작업을 10개만 동시에 해도 메모리가 1GB에 도달하게 되고 서버처럼 다수가 사용할 수 있는 상황에서 메모리 문제가 발생할 수 있다.

 

라고 문제를 제시했다. 그래서 나온것이 스트림으로 한 번에 100MB가가 아니라 조금씩 조금씩 지속적으로 전달하는 방식이라고 보면 된다.

 

스트림

 

 

스트림은 버퍼에 담는 것 까지는 동일하나 버퍼의 내용을 한 번에 보내는 것이 아니라 조금씩 꾸준히 계속 보내는 것을 의미한다.

 

const fs = require('fs');

const readStream = fs.createReadStream('./readme3.txt', { highWaterMark: 16 });
const data = [];

readStream.on('data', (chunk) => {
    data.push(chunk);
    console.log('data :', chunk, chunk.length);
    console.log('middle :', chunk.toString());
});

readStream.on('end', () =>{
    console.log('end :', Buffer.concat(data).toString());
});

readStream.on('error', (err) => {
    console.error('error:', err);
});

 

코드를 chunk라는게 나오는데 스트림으로 보낼때 나눠진 조각을 chunk라고 부른다. data이벤트를 설정하여 chunk가 들어오면 data라는 배열에 하나씩 push된다.

 

그리고 'end'이벤트 발생을 통해서 만약 읽는 것이 끝나면 concat을 통해서 하나로 합쳐서 콘솔에 띄우게 했다. 그리고 중간 과정이 궁금해서 middle : 현재 진행상황을 보여 주도록 했다.

 

 

결과를 보면 글자가 깨지는 부분은 아마 글자로써의 데이터가 덜 구축되서 그런게 아닐까 조심스럽게 짐작해본다. 이런 식으로 데이터를 조금씩 보내는 방식이 스트림이다.

 

그런데 여기서 hightWaterMark가 16인데 default는 64KB라서 대부분의 문자열은 한 번에 전송이 된다. 스트림을 조금씩 보낸다고 했지만 그 조금이 그 조금이 아니더라.

 

버퍼와 스트림에 대해서 알아보았다. 원래도 용어와 대충의 용도는 알고 있었지만 이렇게 눈으로 직접보는 것과는 차이가 있었다. 조금 더 확실하게 이해한 것 같다.

'공부 > Node.js' 카테고리의 다른 글

[Node.js] 넌적스  (0) 2020.08.21
[Node.js] REST  (2) 2020.08.18
[Node.js] 동기와 비동기  (0) 2020.08.14
[Node.js] Promise  (0) 2020.08.14
[Node.js] Do it! Node.js 후기  (0) 2020.08.12