노드 파일 시스템 접근하기
https://nodejs.org/dist/latest-v14.x/docs/api/fs.html
File system | Node.js v14.21.3 Documentation
nodejs.org
fs 모듈은 파일 시스템에 접근하는 모듈이다.
즉, 파일을 생성하거나 삭제하고, 읽거나 쓰고, 폴더를 만들거나 지울 수 있다.
readme.txt
저를 읽어주세요
readFile.js
const fs = require('fs');
fs.readFile('./readme.txt', (err, data) => {
if (err) {
throw err;
}
console.log(data)
console.log(data.toString());
});
console.log(data) 는 Buffer를 출력하기 때문에 toString을 이용해서 문자열로 변환해야 txt파일 내용을 확인 할 수 있다.
fs는 기본적으로 콜백 형식의 모듈이므로 실무에서 사용하기가 불편하다.
fs모듈을 프로미스 형식으로 바꿔보자
readFilePromise.js
const fs = require('fs').promises;
fs.readFile('./readme.txt')
.then((data) => {
console.log(data);
console.log(data.toString());
})
.catch((err) => {
console.error(err);
});
fs 모듈에서 promise 속성을 불러오면 프로미스 기반의 fs 모듈을 사용할 수 있게 된다.
writeFile.js
const fs = require('fs');
fs.writeFile('./writeme.txt', '글이 입력됩니다', (err) => {
if (err) {
throw err;
}
fs.readFile('./writeme.txt', (err, data) => {
if (err) {
throw err;
}
console.log(data.toString());
});
});
1. 동기 메서드와 비동기 메서드
setTimeout 같은 타이머와 process.nextTick 외에도 노드는 대부분 메서드를 비동기 방식으로 처리한다.
하지만 몇몇 메서드는 동기 방식으로 사용할 수 있다. 특히 fs모듈이 그러한 메서드를 많이 가지고 있다.
readme2.txt
저를 여러번 읽어보세요
async.js
const fs = require('fs');
console.log('시작');
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('1번', data.toString());
});
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('2번', data.toString());
});
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('3번', data.toString());
});
console.log('끝');
시작과 끝을 제외하고 결과의 순서는 매번 달라진다.
많은 I/O 요청이 들어와도 메인 스레드는 백그라운드에 요청 처리를 위임한다. 백그라운드가 각각 요청 처리가 완료되었다고 알리면 그때 콜백 함수를 처리하면 된다.
백그라운드에서는 요청 세개를 거의 동시에 실행한다
순서대로 출력하고싶다면 다음 메서드를 사용할 수도 있다.
sync.js
const fs = require('fs');
console.log('시작');
let data = fs.readFileSync('./readme2.txt');
console.log('1번', data.toString());
data = fs.readFileSync('./readme2.txt');
console.log('2번', data.toString());
data = fs.readFileSync('./readme2.txt');
console.log('3번', data.toString());
console.log('끝');
해당 코드는 치명적인 단점이 있다. readFileSync메서드를 사용하면 수백개 요청이 들어올 때 성능에 문제가 생긴다.
Sync메서드를 사용할 때는 이전 작업이 완료가되어야 다음 작업을 진행할 수 있기 때문에 백그라운드가 작업하는 동안 메인 스레드는 대기해야 하므로 비효율적이다.
비동기 fs메서드를 사용하면 백그라운드가 동시에 작업할 수도 있고, 메인 스레드는 다음 작업을 처리할 수 있다.
비동기 방식으로 하되 순서를 유지하고 싶다면 어떻게 해야할까?
asyncOrder.js
const fs = require('fs');
console.log('시작');
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('1번', data.toString());
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('2번', data.toString());
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('3번', data.toString());
console.log('끝');
});
});
});
이전 readFile의 콜백 다음 readFile을 넣으면 된다. 콜백지옥이 펼쳐지지만 적어도 순서가 어긋나는 일은 없다.
콜백 지옥은 Promise나 async/await로 어느정도 해결할 수 있다.
asyncOrderPromise.js
참고 : ⌜node.js 교과서⌟ 책을 공부하며 요약・정리한 내용입니다.