#1. Event
1. Node에서의 이벤트
1) 이벤트란?
- 이벤트란 프로그램이 겪는 어떠한 사건을 말한다. (클릭, 마우스오버, 스크롤 등등)
- 일반적으로 이벤트에 대한 이해는 UI를 갖는 경우를 기준으로 한다.
- Node(백엔드)는 UI가 없기 때문에 사용자의 어떤 행위에 대한 개념은 아니다.
- 그래서 프론트가 접속 했을 때 혹은 프론트가 접속을 해제 했을 때 등의 ~~할 때로 표현할 수 있는 어떤 상황을 의미한다.
※ 이벤트 리스너
- 프로그래머가 정의하거나 프로그램에 정해져 있는 어떤 사건이 발생하는가를 모니터링 하는 기능 (ex. onclick)
※ 이벤트 핸들러
- 이벤트가 발생했을 때 실행되는 단위 기능
- 예를 들어 onclick 속성에 의해 호출되는 어떤 사용자 정의 함수를 말한다.
2) Node에서 이벤트 핸들러 정의하기
- process.on은 document.addEventListener 와 같은 역할을 한다.
process.on('이벤트이름', function(파라미터1, 파라미터2, ... 파라미터n) {
... 이벤트가 발생한 경우 실행될 기능 ...
});
3) 이벤트 핸들러 호출하기
- emit을 활용해서 호출한다.
process.emit('이벤트이름', 파라미터1, 파라미터2, ... 파라미터n);
#2. File Input / Output
1. 파일 입출력
1) I/O
- Input / Output의 줄임말로 프로그램 기준으로 파일이 입력되거나 출력되는 처리.
- 파일입력(read): 프로그램이 해당 파일을 읽어들여서 그 내용을 자신의 변수에 저장한다.
- 파일출력(write): 프로그램이 자신이 갖고 있는 변수의 내용을 외부 파일로 저장한다.
- Node Modules의 fs 모듈을 사용한다.
2) permission
- 파일에 대한 접근 권한.
- 브라우저에서 구동하는 js는 불특정 다수에게 실행되어야 하는파일이므로 특정 환경에 종속적인 코드는 지양하게 된다.
- 백엔드 시스템의 경우 특정 컴퓨터상에서 구동하게 되면 불특정 다수가 그 시스템에 접속하는 형태이기 때문에 다양한 환경에 맞추지 않더라도 영향이 없다.
- 주로 백엔드 시스템은 고사양의 컴퓨터에 일반 개인 사용자용이 아닌 다중 접속을 허용하는 기능을 갖는 운영체제를 설치하고 그 환경에 최적화된 형태로 개발된다. (일반적으로 리눅스 환경)
- 대부분의 백엔드 환경은 리눅스 상에서 구동된다는 전제를 갖는 경우가 많다.
- 내가 만든 파일에 대해 나 이외의 사용자가 읽기(4), 쓰기(2), 실행(1)을 할 수 있는지 여부를 설정할 수 있다.
- node의 fs 모듈이 갖는 chmod( ) 함수를 사용한다.
- 나는 모든 권한 / 그룹은 읽기+쓰기 / 그 밖의 사용자는 실행만 허용 → chmod 761 파일이름
- 모든 권한은 읽기, 쓰기, 실행을 다 더한 값이다. ( 4 + 2 + 1)
※ 리눅스의 사용자 구분
- 자기 자신
- 자신이 속한 그룹
- 그 밖의 사용자
2. 파일 쓰기 / 읽기
실행 하면 파일이 없는 경우 생성, 있다면 삭제한다.
1) 동기식 파일 쓰기 / 읽기
- 파일을 다 저장하기 전 까지는 프로그램이 대기 상태.
- 그러므로 대용량 처리에는 적합하지 않는다.
- writeFileSync: 파일 쓰기
- unlinkSync: 파일 삭제
- readFileSync: 파일 읽기
- existsSync: 파일 존재 여부 확인
- chmodSync: 퍼미션 설정
- 모듈 참조 및 필요한 변수 생성
import fs from 'fs';
const target = './output_sync.txt'; // 저장할 파일의 경로
const content = 'hello world'; // 저장할 내용
const isExists = fs.existsSync(target); // 파일의 존재 여부 검사
- 동기식 파일 쓰기 / 삭제
- 파일이 존재하지 않을 경우 새로 저장한다.
- 반대로 파일이 존재할 경우 삭제.
- 저장할 경로는 상대, 절대 경로 모두 사용 가능하다.
- 상대 경로인 경우 에디터에 설정된 작업 디렉토리가 기준.
- 절대 경로인 경우 컴퓨터 전역에 대해서 저장 가능.
if(!isExists) {
// 파일 생성
fs.writeFileSync(target, content, 'utf8');
// 퍼미션 설정
fs.chmodSync(target, '0766');
// 파일 저장이 완료된 후에나 메세지가 표시된다.
console.log('파일에 데이터 쓰기 및 퍼미션 설정 완료');
} else {
// 파일이 존재할 경우 파일 삭제
fs.unlinkSync(target);
console.log('파일 삭제 완료');
};
- 동기식 파일 읽기
- 파일을 동기식으로 읽어서 그 내용을 리턴한다.
- 이 파일을 다 읽기 전 까지는 프로그램이 대기상태.
- 대용량 처리에는 적합하지 않음.
if(fs.existsSync(target)) {
// 파일 읽기
const data = fs.readFileSync(target, 'utf8');
// 읽어 들인 데이터를 출력
console.log(data) // hello world
} else {
console.log(target + '파일이 존재하지 않습니다.')
};
2) 비동기식 파일 쓰기 / 읽기
- 동기식에서 사용한 함수에서 뒤에 sync만 빼면 된다.
- writeFile: 파일 쓰기
- unlink: 파일 삭제
- readFile: 파일 읽기
- chmod: 퍼미션 설정
- 모듈 참조 및 필요한 변수 생성
import fs from 'fs';
const target = './output_async.txt'; // 저장할 파일의 경로
const content = 'hello world'; // 저장할 내용
const isExists = fs.existsSync(target); // 파일의 존재 여부 검사
- 비동기식 파일 쓰기 / 삭제
if(!isExists) {
// 파일 쓰기
fs.writeFile(target, content, 'utf8', err => {
console.debug(target + ' 에 데이터 쓰기 완료.');
if(err) {
console.error(err);
return;
}
// 퍼미션 설정
fs.chmod(target, '0766', err => {
if(err) {
console.error(err);
return;
}
console.debug(target + ' 의 퍼미션 설정 완료');
});
console.debug(target + ' 의 퍼미션 설정을 요청했습니다.');
});
console.debug(target + ' 의 파일 저장을 요청했습니다.');
} else {
// 파일 삭제
fs.unlink(target, err => {
if(err) {
console.error(err);
return;
}
console.debug(target + ' 의 파일 삭제 완료');
});
console.debug(target + ' 의 파일 삭제를 요청했습니다.');
};
- 비동기식 파일 읽기
if(fs.existsSync(target)) {
// 파일 읽기
fs.readFile(target, 'utf8', (err, data) => {
if(err) {
console.error(err);
return;
}
console.debug(data); // 읽어들인 데이터 출력
});
console.debug(target + ' 파일을 읽도록 요청했습니다.');
} else {
console.debug(target + '파일이 존재하지 않습니다.');
};
3) Promise 방식으로 파일 쓰기 / 읽기
- 모듈 참조 및 필요한 변수 생성
import fs from 'fs';
const target = './output_promise.txt'; // 저장할 파일의 경로
const content = 'hello World'; // 저장할 내용
const isExists = fs.existsSync(target); // 파일의 존재 여부 검사
- Promise 파일 쓰기 / 삭제
if(!isExists) {
// 파일이 존재하지 않다면 파일 생성
const myPromise = fs.promises.writeFile(target, content);
myPromise
.then(() => {
console.debug('저장완료');
})
.catch(e => {
console.error('저장실패');
console.error(e);
});
console.log(target + ' 의 파일 저장을 요청했습니다.');
} else {
// 파일이 존재할 경우 삭제
fs.promises
.unlink(target)
.then(() => {
console.debug('삭제완료');
})
.catch(e => {
console.error('삭제실패');
console.error(e);
});
console.log(target + ' 의 파일 삭제를 요청했습니다.');
};
- Promise 파일 읽기
if(fs.existsSync(target)) {
fs.promises
.readFile(target, 'utf8')
.then(data => {
// 읽은 결과를 받기 위한 콜백
console.debug('파일읽기 완료');
console.debug(data);
})
.catch(err => {
// 에러 발생기 호출되는 콜백
console.error(err);
console.error('파일읽기 실패');
});
console.log(target + ' 파일을 읽도록 요청했습니다.');
} else {
console.log(target + ' 파일이 존재하지 않습니다.');
};
4) async & await 방식으로 파일 쓰기 / 읽기
- 모듈 참조 및 필요한 변수 생성
import fs from 'fs';
const target = './output_await.txt'; // 저장할 파일의 경로
const content = 'hello World'; // 저장할 내용
const isExists = fs.existsSync(target); // 파일의 존재 여부 검사
- async & await 파일 쓰기 / 삭제
if(!isExists) {
(async () => {
try {
// 성공시에 아무런 결과도 반환하지 않으므로 리턴받지 않음.
await fs.promises.writeFile(target, content);
console.debug('저장완료');
} catch(err) {
console.error('에러발생');
console.error(err);
}
})();
console.log(target + ' 의 파일 저장을 요청했습니다.');
} else {
(async () => {
try {
await fs.promises.unlink(target);
console.debug('삭제완료');
} catch(err) {
console.error('에러발생');
console.error(err);
}
})();
};
- async & await 파일 읽기
if(fs.existsSync(target)) {
(async () => {
let data = null;
try {
data = await fs.promises.readFile(target, 'utf8');
console.debug('파일읽기 완료');
} catch(err) {
console.error(err);
console.error('파일읽기 실패');
}
console.debug(data); // hello world
})();
console.log(target + ' 파일을 읽도록 요청했습니다.');
} else {
console.log(target + ' 파일이 존재하지 않습니다.');
};
3. 디렉토리 쓰기 / 읽기
실행하면 디렉토리가 없는 경우 생성, 디렉토리가 있다면 삭제한다.
1) 동기식 디렉토리 쓰기 / 읽기
- mkdirSync: 디렉토리 쓰기
- remdirSync: 디렉토리 삭제
- existsSync: 디렉토리 존재 여부 확인
- chmodSync: 퍼미션 설정
- 모듈 참조 및 필요한 변수 생성
import fs from 'fs';
const target = './docs';
- 동기식 디렉토리 쓰기 / 삭제
- 기본적으로 비어있지 않은 폴더는 삭제할 수 없다.
if(!fs.existsSync(target)) {
console.log(target + ' 경로가 존재하지 않기 때문에 생성합니다.');
fs.mkdirSync(target); // 폴더 생성하기 (오래걸리는 작업이 아니므로 동기 처리)
fs.chmodSync(target, '0755'); // 생성된 폴더에 대한 퍼미션 설정
console.log(target + '(이)가 생성되었습니다');
} else {
console.log(target + ' 경로가 존재하므로 삭제합니다.');
fs.rmdirSync(target); // 폴더 삭제하기 -> 비어있지 않은 폴더는 삭제할 수 없다.
console.log(target + '(이)가 삭제되었습니다.');
};
/* 출력
./docs 경로가 존재하지 않기 때문에 생성합니다.
./docs(이)가 생성되었습니다
*/
2) 비동기식 디렉토리 쓰기 / 읽기
- mkdir: 디렉토리 쓰기
- remdir: 디렉토리 삭제
- 모듈 참조 및 필요한 변수 생성
import fs from 'fs';
const target = './docs';
- 비동기식 디렉토리 쓰기 / 삭제
if(!fs.existsSync(target)) {
fs.mkdir(target, (err) => {
if(err) {
console.error(err);
return;
}
fs.chmodSync(target, '0777');
console.log('새로운 %s 폴더를 만들었습니다.', target);
});
console.log('%s 폴더의 생성을 요청했습니다.', target);
} else {
fs.rmdir(target, (err) => {
if(err) {
return console.log(err);
}
console.log('%s 폴더를 삭제했습니다.', target);
});
console.log('%s 폴더의 삭제를 요청했습니다.', target);
};
/*
./docs 폴더의 생성을 요청했습니다.
새로운 ./docs 폴더를 만들었습니다.
*/
3) async & await 디렉토리 쓰기 / 읽기
- 모듈 참조 및 필요한 변수 생성
- 중간 폴더가 존재하지 않을 경우 에러
import fs from 'fs';
const target = './docs';
- async & await 디렉토리 쓰기 / 삭제
f(!fs.existsSync(target)) {
(async () => {
try {
await fs.promises.mkdir(target);
await fs.promises.chmod(target, '0777');
console.debug('디렉토리 생성 완료');
} catch(e) {
console.error('디렉토리 생성 에러');
console.error(e);
}
})();
console.log(`${target} 폴더의 생성을 요청했습니다.`);
} else {
(async () => {
try {
await fs.promises.rmdir(target);
console.debug('디렉토리 삭제 완료');
} catch(e) {
console.error('디렉토리 삭제 에러');
console.error(e);
}
})();
console.log(`${target} 폴더의 삭제를 요청했습니다.`);
};
/* 출력
./docs 폴더의 생성을 요청했습니다.
디렉토리 생성 완료
*/
'국비수업 > Node.js' 카테고리의 다른 글
[Node.js] HTTP Client (0) | 2022.06.27 |
---|---|
[Node.js] Scheduler (0) | 2022.06.27 |
[Node.js] Log (0) | 2022.06.27 |
[Node.js] Node Modules (0) | 2022.06.23 |
[Node.js] Node.js 개념 이해하기 (0) | 2022.06.23 |