주요 내장 모듈 살펴보기 🔍
Node.js에는 별도의 설치 없이 require()를 통해 바로 사용할 수 있는 다양한 내장 모듈들이 있습니다. 이 모듈들은 파일 시스템 제어, HTTP 통신, 운영체제 정보 접근 등 서버 개발에 필수적인 기능들을 제공합니다. 마치 Java의 표준 라이브러리 (JDK에 포함된 java.lang, java.io, java.net 등)와 같다고 생각하시면 됩니다.
이번 섹션에서는 가장 자주 사용되고 중요한 몇 가지 내장 모듈을 중심으로 살펴보겠습니다.
1. fs (File System) 모듈: 파일 다루기의 모든 것 📁
fs 모듈은 파일 시스템과 상호작용하는 데 필요한 모든 기능을 제공합니다. 파일 읽기, 쓰기, 디렉토리 생성 및 삭제, 파일 정보 확인 등 다양한 작업을 수행할 수 있습니다. Java의 java.io.File, java.nio.file.Files, java.nio.file.Path 클래스들이 제공하는 기능과 유사합니다.
fs 모듈의 함수들은 대부분 동기(synchronous) 방식과 비동기(asynchronous) 방식을 모두 지원합니다.
- 비동기 방식: 함수 이름 뒤에 Sync가 붙지 않은 함수들입니다. (예: fs.readFile(), fs.writeFile())
- 작업이 완료될 때까지 기다리지 않고 다음 코드로 넘어갑니다. (논블로킹)
- 결과는 마지막 인자로 전달되는 콜백 함수를 통해 처리됩니다. 이 콜백 함수는 보통 첫 번째 인자로 에러 객체(err)를 받고, 두 번째 인자로 작업 결과(data)를 받습니다.
- Node.js에서는 I/O 작업 시 비동기 방식을 사용하는 것이 일반적이며 권장됩니다. 서버의 응답성을 유지하는 데 중요하기 때문입니다.
- 동기 방식: 함수 이름 뒤에 Sync가 붙습니다. (예: fs.readFileSync(), fs.writeFileSync())
- 작업이 완료될 때까지 코드 실행이 멈춥니다. (블로킹)
- 결과는 함수 반환 값으로 직접 받습니다. 에러 발생 시 예외(exception)를 던집니다.
- 간단한 스크립트나 애플리케이션 시작 시 초기 설정 파일 읽기 등 제한적인 경우에만 사용하는 것이 좋습니다. 서버 환경에서는 동기 방식을 남용하면 성능 저하의 원인이 될 수 있습니다.
주요 fs 모듈 함수 예시 (비동기 방식 위주):
- fs.readFile(path[, options], callback): 파일의 내용을 비동기적으로 읽습니다.
- path: 읽을 파일의 경로입니다.
- options (선택 사항): 인코딩 방식 (예: 'utf8')이나 flag 등을 객체 또는 문자열로 지정할 수 있습니다. 지정하지 않으면 Buffer 객체로 반환됩니다.
- callback(err, data): 파일 읽기가 완료되거나 오류 발생 시 호출되는 함수입니다.
-
const fs = require('fs'); fs.readFile('example.txt', 'utf8', (err, data) => { if (err) { console.error('파일 읽기 오류:', err); return; } console.log('파일 내용:', data); }); - JavaScript
- fs.writeFile(file, data[, options], callback): 파일에 데이터를 비동기적으로 씁니다. 파일이 없으면 새로 만들고, 있으면 내용을 덮어씁니다.
-
JavaScript
const fs = require('fs'); const content = 'Hello, Node.js File System!'; fs.writeFile('newFile.txt', content, 'utf8', (err) => { if (err) { console.error('파일 쓰기 오류:', err); return; } console.log('파일 쓰기 완료!'); }); - fs.appendFile(path, data[, options], callback): 파일에 데이터를 비동기적으로 추가합니다. 파일이 없으면 새로 만듭니다.
-
JavaScript
const fs = require('fs'); const moreContent = '\nAppending new content.'; fs.appendFile('newFile.txt', moreContent, 'utf8', (err) => { if (err) { console.error('파일 이어쓰기 오류:', err); return; } console.log('파일 이어쓰기 완료!'); }); - fs.exists(path, callback) (Deprecated): 파일이나 디렉토리의 존재 여부를 확인합니다.
- 주의: fs.exists는 콜백의 첫 번째 인자로 에러가 아닌 boolean 값(존재 여부)을 전달하여 일반적인 Node.js 콜백 패턴과 다르고, 경쟁 상태(race condition)를 유발할 수 있어 Deprecated 되었습니다.
- 대신 fs.stat()이나 fs.access()를 사용하여 파일의 상태를 확인하거나 접근 가능 여부를 체크하는 것이 권장됩니다.
JavaScriptconst fs = require('fs'); // fs.stat() 사용 예시 fs.stat('example.txt', (err, stats) => { if (err) { if (err.code === 'ENOENT') { console.log('파일 또는 디렉토리가 존재하지 않습니다.'); } else { console.error('상태 확인 오류:', err); } return; } console.log('파일 정보:', stats); console.log('파일인가요?', stats.isFile()); console.log('디렉토리인가요?', stats.isDirectory()); }); // fs.access() 사용 예시 (접근 권한 확인) fs.access('example.txt', fs.constants.F_OK | fs.constants.R_OK, (err) => { if (err) { console.error('파일이 존재하지 않거나 읽을 수 없습니다.'); } else { console.log('파일이 존재하고 읽을 수 있습니다.'); } });- fs.constants.F_OK: 파일 존재 여부
- fs.constants.R_OK: 읽기 권한
- fs.constants.W_OK: 쓰기 권한
- fs.constants.X_OK: 실행 권한 (Windows에서는 파일이 존재하기만 하면 실행 가능으로 간주)
- fs.mkdir(path[, options], callback): 디렉토리를 비동기적으로 생성합니다.
-
JavaScript
const fs = require('fs'); fs.mkdir('./myNewDirectory', { recursive: true }, (err) => { // recursive: true 옵션은 부모 디렉토리도 함께 생성 if (err) { console.error('디렉토리 생성 오류:', err); return; } console.log('디렉토리 생성 완료!'); }); - fs.readdir(path[, options], callback): 디렉토리의 내용을 (파일 및 하위 디렉토리 이름 배열) 비동기적으로 읽습니다.
-
JavaScript
const fs = require('fs'); fs.readdir('.', (err, files) => { // '.'은 현재 디렉토리를 의미 if (err) { console.error('디렉토리 읽기 오류:', err); return; } console.log('현재 디렉토리 내용:', files); }); - fs.unlink(path, callback): 파일을 비동기적으로 삭제합니다. (Java의 File.delete())
- fs.rmdir(path, callback): 디렉토리를 비동기적으로 삭제합니다. (비어있는 디렉토리만 삭제 가능, recursive: true 옵션을 통해 내용이 있어도 삭제 가능 (fs.rm 권장))
- fs.rm(path, [options], callback) (Node.js v14.14.0 이상 권장): 파일 및 디렉토리를 비동기적으로 삭제합니다. recursive: true 옵션을 통해 디렉토리 내부까지 삭제할 수 있습니다.
- fs.rename(oldPath, newPath, callback): 파일 또는 디렉토리의 이름을 변경하거나 위치를 이동합니다.
Promise 기반의 fs 모듈 사용 (fs.promises)
Node.js v10부터 fs 모듈은 프로미스(Promise)를 반환하는 API도 제공합니다. 콜백 지옥을 피하고 async/await와 함께 사용하기 편리합니다.
const fs = require('fs').promises; // .promises를 붙여서 가져옵니다.
async function readFileAsync() {
try {
const data = await fs.readFile('example.txt', 'utf8');
console.log('파일 내용 (async/await):', data);
await fs.writeFile('newFileAsync.txt', 'Written with async/await!');
console.log('파일 쓰기 완료 (async/await)!');
} catch (err) {
console.error('오류 발생:', err);
}
}
readFileAsync();
Java 개발자에게는 콜백 스타일보다는 try-catch와 함께 사용하는 async/await 패턴이 더 익숙하고 직관적일 수 있습니다.
fs 모듈은 매우 다양한 기능을 제공하므로, 필요할 때마다 Node.js 공식 문서를 참고하여 적절한 함수와 옵션을 찾아 사용하는 것이 좋습니다.
'프로그래밍 > NODEJS 강좌 BY GEMINI' 카테고리의 다른 글
| 주요 내장 모듈 살펴보기-path: 파일 및 디렉토리 경로 처리 (Java의 java.nio.file.Path와 유사) (0) | 2025.06.04 |
|---|---|
| 주요 내장 모듈 살펴보기- http: HTTP 서버 및 클라이언트 생성 (Java의 java.net.HttpURLConnection 또는 서블릿 API와 비교) (0) | 2025.06.04 |
| 2️⃣ Node.js 핵심 모듈: 강력한 기본기 다지기 (0) | 2025.05.28 |
| Java vs. Node.js: 서버 사이드 패러다임 비교 🔄 (0) | 2025.05.28 |
| Hello Node.js! - 첫 애플리케이션 작성 (1) | 2025.05.27 |