파일을 가져오는데 한 번에 파일을 불러오는 방식이 아닌 일정 크기만큼 반복하여 메모리에서 데이터를 가져오는 작업이라 할 수 있다.
효율적이지 않은 방법
→ 한 번에 읽어서 한 번에 쓴다면 비효율적으로 동작할 것이다. 예를 들어 100MB 크기의 파일을 전부 읽어서 다시 다른 파일에 쓴다면 읽고 쓰는데 많은 시간과 리소스 소모가 클 것이다.
const fs = require('fs');
const beforeMem = process.memoryUsage().rss;
fs.readFile('./text.txt', (_, data) => {
fs.writeFile('./text2.txt', data, () => { });
// calculate
const afterMem = process.memoryUsage().rss;
const diff = afterMem - beforeMem;
const consumed = diff / 1024 / 1024;
console.log(diff);
console.log(`Consumed Memory: ${consumed}MB`);
});
효율적인 방법
→ 한줄 한줄, 일정 크기 만큼 반복하면서 읽고, 쓴다면 효율적으로 동작할 것이다. 즉 Stream을 사용하면 된다.
const fs = require('fs');
// 스트림 생성 및 옵션 설정 (createReadStream)
const readStream = fs.createReadStream('./file.txt', {
highWaterMark: 8, // Buffer가 한번 가져와서 읽고 처리하는 크기 설정, default: 64 kbytes
encoding: 'utf8', // 인코딩 방식 설정
});
const data = [];
// 스트림 이벤트 설정 (on)
// on : 이벤트가 발생할 때 마다 실행
readStream.on('data', (chunk) => {
console.count(`---@@@${chunk}@@@---`);
data.push(chunk);
});
readStream.on('error', (error) => {
console.error(error);
});
readStream.on('end', () => {
console.log(data.join(''));
console.log('The End');
});
// 스트림 이벤트 설정 (once)
// once : 처음 이벤트가 발생할 때 한 번만 실행
readStream.once('data', (chunk) => {
console.count(`---@@@${chunk}@@@---`);
});
const fs = require('fs');
const writeStream = fs.createWriteStream('./file3.txt');
writeStream.on('finish', () => {
console.log('finished!');
})
writeStream.write('hello!');
writeStream.write('world!');
writeStream.end();
readFile과 readStream이 다른점
readFile은 한 번에 전부 읽어서 가져오는 반면, readStream은 일정 크기 간격으로 가져와서 읽고, 이벤트가 발생하고 이를 반복한다는 점이다.
두 개의 Stream을 이어준다.