JavaScript ES 입출력 - fs 모듈, readline 모듈

dev_joo·2024년 10월 23일
post-thumbnail

fs 모듈

파일 시스템과 상호작용하기 위한 기능을 제공하는 모듈로,
파일을 읽고, 쓰고, 삭제하고, 디렉토리를 만들고 관리하는 등 다양한 파일 시스템 작업을 할 수 있다.

Node 홈페이지에서는 다음과 같이 설명한다.

The fs module enables interacting with the file system in a way modeled on standard POSIX functions.
(fs 모듈은 POSIX 기능의 표준에 맞춰진 방식으로 파일 시스템과 상호작용 가능하게 하는 모듈이다.)

(서버 환경이 UNIX 또는 UNIX-like 시스템(예: 리눅스, macOS 등)에서 운영되기 때문에 UNIX 기반 운영 체제에서 호환성을 보장하기 위해 정의된 표준 POSIX(Portable Operating System Interface)의 원칙을 따른 것으로 보인다.)

코딩테스트에서는 먼저 문제 입력을 전부 받은 후에 계산 처리를 하고 정답을 출력하는 과정에서
처리 도중 사용자와 상호작용할 필요가 없기 때문에 이벤트 드라이븐 방식의 readline대신 fs모듈을 사용하는 것이 낫다.


각 줄에 나눠진 숫자 더하기(동기 방식)

/* 
1
2
3
4
5
6
*/

const fs = require('fs'); //fs 모듈 객체 생성
//import * as fs from 'fs';

// 표준 입력에서 데이터 읽기
const input = fs.readFileSync(0, "utf8");

// 입력을 줄 단위로 나누기
const lines = input.trim().split('\n');

// 계산 예시: 각 줄의 숫자를 더하기
let sum = 0;
for (const line of lines) {
    sum += parseInt(line, 10);
}
// 윈도우 - 입력을 종료하려면 터미널에 Ctrl+Z 입력
// 결과 출력 (21)
console.log(sum);

fs 모듈의 대표적인 기능과 함수

  1. 파일 읽기/쓰기:
    fs.readFile(): 파일의 내용을 비동기적으로 읽기
    fs.writeFile(): 파일에 데이터를 비동기적으로 쓰기 파일이 없으면 새로 생성
  2. 파일 상태 확인:
    fs.stat(): 파일 또는 디렉토리의 메타데이터를 조회 (예: 크기, 수정 시간 등)
  3. 파일 삭제:
    fs.unlink(): 지정된 파일을 삭제
  4. 디렉토리 작업:
    fs.mkdir(): 새 디렉토리를 생성
    fs.rmdir(): 비어 있는 디렉토리를 삭제
    fs.readdir(): 디렉토리의 파일 목록 읽기
  5. 파일 복사 및 이동:
    fs.copyFile(): 파일 복사
    fs.rename(): 파일의 이름을 변경하거나 다른 위치로 이동
  6. 스트림 (대용량 파일의 효율적 처리):
    fs.createReadStream(): 파일을 읽기 위한 스트림을 생성
    fs.createWriteStream(): 파일을 쓰기 위한 스트림을 생성
  7. 파일 모니터링:
    fs.watch(): 파일이나 디렉토리의 변화를 감지 (변경, 삭제, 생성 등)
  8. 비동기 방식 - 콜백, 프로미스 기반 API :
    fs.promises.readFile()
    fs.readFile(()=>{})

+ promise 기반 입력받기

const fs = require('fs').promises;
// 비동기 함수 main() 정의
const main = async () => {
    try {
        const data = await fs.readFile('input.txt', 'utf8');
        const lines = data.trim().split('\n');
        let sum = 0;
        for (const line of lines) {
            sum += parseInt(line, 10);
        }
        console.log('합계:', sum);
    } catch (err) {
        console.error('파일을 읽는 데 오류 발생:', err);
    }
};

// 프로그램 시작
main();

+ callback 기반 입력받기

const fs = require('fs');

// 읽을 파일 이름
const filename = 'example.txt';

// 파일을 비동기적으로 읽기
fs.readFile(filename, 'utf8', (err, data) => {
    if (err) {
        console.error('파일 읽기 오류:', err);
        return;
    }
    console.log('파일 내용:', data);
});

readline 모듈

readline 모듈은 사용자로부터 콘솔 입력을 읽고, 입력에 대한 응답을 처리하는 데 사용된다.

사용자와의 인터랙션 부분에 더 중점을 둔 CLI 입출력 처리라는 것에 fs 모듈과 차이가 있다.

The readline module provides an interface for reading data from a Readable stream (such as process.stdin) one line at a time. It can be accessed using:
(readline 모듈은 읽기 가능한 stream으로부터 (process.stdin등) 데이터를 읽기 위한 인터페이스를 제공한다.)

readline은 readline.createInterface() 객체로 이벤트 기반으로 표준 입출력 스트림의 입력, 출력에 관여한다.

대화형 입력 받기

이벤트 리스너

rl.on([line/close / pause /resume /SIGINT ...])

const readline = require('readline');
// import { createInterface as ci } from 'readline';

const rl = readline.createInterface({
//const rl = ci({
    input: process.stdin,
    output: process.stdout
});

console.log('여러 줄을 입력 받습니다. (종료하려면 "exit" 입력)');

rl.on('line', (line) => {
    console.log(`입력된 줄: ${line} (종료하려면 "exit" 입력)`);
    if (line.toLowerCase() === 'exit') {
        rl.close();  // 'exit' 입력 시 종료
    }
}).on('close', () => {
    console.log('종료합니다.');
});

rl.question(query, callback)

const readline = require('readline');
// import { createInterface as ci } from 'readline';

const rl = readline.createInterface({
//const rl = ci({
    input: process.stdin,
    output: process.stdout
});

const form = ()=>{
    rl.question('Node.js 어떠신가요? (종료하려면 "exit" 입력)\n', (answer) => {
        
        if (answer.toLowerCase() === 'exit') {
            rl.close();
            process.exit(0);  // 프로세스 종료
        }
        else{
        console.log(`귀중한 피드백에 감사드립니다. : ${answer}`);
        form();
        }
    });
}

form();

이벤트 리스너 공부를 추가로 해봐야겠다.

문서에 나온 이벤트 활용법 :

1. line

입력 스트림에서 개행문자 (\n, \r, or \r\n)가 입력되었을 때 발생(emitted)된다.
예)
사용자가 입력을 마치고 엔터 키를 누를 때

한 줄씩 입력을 받을 때 주로 사용

//콜백 함수에 입력된 한 줄의 문자열 값이 들어간다.
rl.on('line', (input) => {
    console.log(`입력된 줄: ${input}`);
});

2. pause

  • 입력스트림이 일시중지 될때
  • 입력스트림이 일시중지 되지 않았지만 SIGCONT 또는
    SIGINT이벤트를 받았을 때

예) 실행 중 (Ctrl+Z) 또는 (Ctrl+C) 입력했을 때

특정 조건에서 입력을 중지하고자 할 때 사용

rl.on('pause', () => {
    console.log('입력이 일시 중지되었습니다.');
});

3. resume

인터페이스가 다시 활성화될 때 발생

입력이 재개될 때 어떤 작업을 수행하고자 할 때 사용

rl.on('resume', () => {
    console.log('입력이 다시 활성화되었습니다.');
});

4. close

readline.Interface 인스턴스의 입출력 스트림 제어가 해제되며, 인스턴스에 연결되었던 모든 핸들러가 비활성화된다. 즉, 더이상 입력 이벤트를 수신하지 않는다.

입력 스트림이 종료될 때 마지막 처리

rl.on('close', () => {
    console.log('프로그램을 종료합니다.');
    process.exit(0);
});
profile
풀스택 연습생. 끈기있는 삽질로 무대에서 화려하게 데뷔할 예정 ❤️🔥

0개의 댓글