pipe와 스트림 메모리 효율

김무연·2023년 12월 12일

Backend

목록 보기
22/49

createReadStream으로 파일을 읽고 그 스트림을 전달받아 createWriteStream으로 파일을 쓸 수 있다. (파일 복사 유사)

이렇게 스트림끼리 연결하는 것을 '파이핑'이라고 한다.

즉 stream으로 분할받아 받아온 데이터를 조작이 가능하다.

예시를 보면 아래와 같다

const fs = require('fs');

const readStream = fs.createReadStream('ch06/readme.txt', {highWaterMark: 16});
const writeStream = fs.createWriteStream('ch06/writeme.txt')
readStream.pipe(writeStream)

readme에서 데이터를 16바이트 씩 받아온 후 readStream에 pipe를 연결해 write에 받아온 데이터를 16바이트 씩 써주게 된다. 이렇게 될 경우 readme에 있는 내용이 writeme에 적혀지게 되어 복사와 유사하게 된다.

압축해서 넣어주기

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

const readStream = fs.createReadStream('ch06/readme.txt', { highWaterMark: 16 });
const zlibStream = zlib.createGzip();
const writeStream = fs.createWriteStream('ch06/writeme.txt')
readStream.pipe(zlibStream).pipe(writeStream)

위의 코드를 보면 zlib를 이용해서 파일을 압축해준 뒤 writeStream을 통해 써주게 된다. 이 처럼 분할해서 받아온 데이터를 .pipe().pipe()를 통해서 데이터를 조작이 계속 가능하게 됨

버퍼와 스트림의 메모리 효율 차이

test를 위해 1GB 정도 되는 txt 파일을 만들어서 복사를 하는데 드는 메모리 사용량을 비교해 볼것이다

const fs = require('fs');

const file = fs.createWriteStream('ch06/big.txt')

for (let i = 0; i <= 10_000_000; i++) {
  file.write('안녕하세요. 엄청나게 큰 파일을 만들어 볼 것입니다. 각오 단단히 하세요 \n');

}

file.end(() => console.log("끝"))

위와 같이 1GB정도 되는 파일을 하나 생성해 준다

이를 buffer방식과 stream방식으로 메모리 사용량을 memoryUsage()를 통해 비교해준다

Buffer 방식

const fs = require('fs');

console.log('before : ', process.memoryUsage().rss);

const data1 = fs.readFileSync('ch06/big.txt')
fs.writeFileSync('ch06/buffer.txt', data1)
console.log('buffer : ', process.memoryUsage().rss)

결과를 보면 서버 메모리 사용량이 23MB 였던게 1GB 이상으로 올랐다. 이런 식이면 여러 사람이 사용할 경우 서버 메모리가 부족할 경우 금방 터지게 될 것이다.

const fs = require('fs');

console.log('before : ', process.memoryUsage().rss);

const readStream = fs.createReadStream('ch06/big.txt')
const writeStream = fs.createWriteStream('ch06/stream.txt')
readStream.pipe(writeStream);
readStream.on('end', () => {
  console.log('stream : ', process.memoryUsage().rss)
})

반면 stream 방식은 23MB 에서 48MB로 1GB파일을 복사하는데 25MB 정도 밖에 오르지 않았다. 즉 파일 복사나 이러한 경우 stream 방식을 사용하는 것이 효율적이다.

기타 메서드

파일 및 폴더 생성, 삭제, 확인...

공식 홈페이지 api docs를 참고하면 자세하게 나와 있음..
https://nodejs.org/dist/latest-v21.x/docs/api/fs.html

profile
Notion에 정리된 공부한 글을 옮겨오는 중입니다... (진행중)

0개의 댓글