Node.js

버퍼와 스트림

쿠와와 2020. 12. 12. 13:50

버퍼: 일정한 크기로 모아두는 데이터   ( 한번에 보내는 것 )

  데이터를 모으다가 일정한 크기가 되면 한 번에 처리

  버퍼링: 버퍼에 데이터가 찰 때까지 모으는 작업

 

스트림: 데이터의 흐름   ( 여러번에 나눠서 보내는 것 )  -> 보통 스트림이 더 좋음

  일정한 크기로 나눠서 여러 번에 걸쳐서 처리

  버퍼(또는 청크)의 크기를 작게 만들어서 주기적으로 데이터를 전달

  스트리밍: 일정한 크기의 데이터를 지속적으로 전달하는 작업

 

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);

buffer 

 

stream

const fs = require('fs');

// stream -> 한번에 64kb 를 받아오는데 파일이 너무 작으면 효율적이지 못함 우리는 예시를 위해
// highWaterMark를 16byte를 사용할 것임
const readStream = fs.createReadStream('./readme3.txt', { highWaterMark: 16 });
const data = [];

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

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

// 비동기 -> error 처리해줘야함
readStream.on('error', (err) => {
  console.log('error :', err);
});

 

파일 읽는 스트림 사용하기

 

fs.createReadStream

createReadStream에 인자로 파일 경로와 옵션 객체 전달

highWaterMark 옵션은 버퍼의 크기(바이트 단위, 기본값 64KB)

data(chunk 전달), end(전달 완료), error(에러 발생) 이벤트 리스너와 같이 사용

 

pipe로 여러 개의 스트림을 이을 수 있음

스트림으로 파일을 복사하는 예제

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

const readStream = fs.createReadStream('readme4.txt');
const zlibStream = zlib.createGzip();   // 압축
const writeStream = fs.createWriteStream('writeme3.txt');
// 그냥 보냄
// readStream.pipe(writeStream);
// 압축해서 보냄
readStream.pipe(zlibStream).pipe(writeStream);

메모리 체크하기

buffer vs stream

 

19 Mb( 기존 ) -> 1GB (서버 메모리)                           19Mb( 기존 ) -> 31MB ( 서버 메모리 )

스트림이 서버의 효율을 많이 올려준다. 사용해보자.