728x90
반응형
1. 파일 삭제
1.1 unlink - 파일 삭제
const fs = require('fs');
// 콜백 방식
fs.unlink('file.txt', (err) => {
if (err) {
console.error('파일 삭제 오류:', err);
return;
}
console.log('파일이 삭제되었습니다.');
});
// 동기 방식
try {
fs.unlinkSync('file.txt');
console.log('파일이 삭제되었습니다.');
} catch (err) {
console.error('파일 삭제 오류:', err);
}
1.2 Promise 기반 삭제
const fs = require('fs').promises;
async function deleteFile(filepath) {
try {
await fs.unlink(filepath);
console.log('파일이 삭제되었습니다.');
} catch (err) {
if (err.code === 'ENOENT') {
console.log('파일이 존재하지 않습니다.');
} else {
throw err;
}
}
}
await deleteFile('example.txt');
1.3 rm - 파일/디렉토리 삭제 (Node.js 14.14+)
const fs = require('fs').promises;
// 파일 삭제
await fs.rm('file.txt');
// 디렉토리 재귀 삭제 (내부 파일 포함)
await fs.rm('folder', { recursive: true });
// 존재하지 않아도 오류 없이 진행
await fs.rm('maybe-exists.txt', { force: true });
// 재귀 + 강제 삭제
await fs.rm('folder', { recursive: true, force: true });
2. 파일 이동
2.1 rename - 이름 변경/이동
const fs = require('fs');
// 콜백 방식
fs.rename('old.txt', 'new.txt', (err) => {
if (err) throw err;
console.log('파일 이름이 변경되었습니다.');
});
// 다른 디렉토리로 이동
fs.rename('file.txt', 'backup/file.txt', (err) => {
if (err) throw err;
console.log('파일이 이동되었습니다.');
});
2.2 Promise 기반 이동
const fs = require('fs').promises;
async function moveFile(source, destination) {
try {
await fs.rename(source, destination);
console.log(`${source} → ${destination} 이동 완료`);
} catch (err) {
if (err.code === 'EXDEV') {
// 다른 파일 시스템 간 이동 시 복사 후 삭제
await fs.copyFile(source, destination);
await fs.unlink(source);
console.log(`${source} → ${destination} 이동 완료 (복사 방식)`);
} else {
throw err;
}
}
}
await moveFile('temp/data.txt', 'archive/data.txt');
2.3 동기 방식
const fs = require('fs');
try {
fs.renameSync('old-name.txt', 'new-name.txt');
console.log('이름 변경 완료');
} catch (err) {
console.error('오류:', err);
}
3. 파일 복사
3.1 copyFile
const fs = require('fs').promises;
// 기본 복사
await fs.copyFile('source.txt', 'dest.txt');
// 대상 파일이 있으면 오류 발생 (덮어쓰기 방지)
await fs.copyFile('source.txt', 'dest.txt', fs.constants.COPYFILE_EXCL);
// 콜백 방식
fs.copyFile('source.txt', 'dest.txt', (err) => {
if (err) throw err;
console.log('복사 완료');
});
3.2 복사 플래그
const fs = require('fs').promises;
// 덮어쓰기 방지
const COPYFILE_EXCL = fs.constants.COPYFILE_EXCL;
// copy-on-write (지원되는 파일 시스템에서)
const COPYFILE_FICLONE = fs.constants.COPYFILE_FICLONE;
// copy-on-write 시도, 실패 시 일반 복사
const COPYFILE_FICLONE_FORCE = fs.constants.COPYFILE_FICLONE_FORCE;
await fs.copyFile('src.txt', 'dst.txt', COPYFILE_EXCL);
3.3 cp - 디렉토리 복사 (Node.js 16.7+)
const fs = require('fs').promises;
// 디렉토리 재귀 복사
await fs.cp('source-folder', 'dest-folder', { recursive: true });
// 옵션
await fs.cp('src', 'dst', {
recursive: true, // 하위 디렉토리 포함
force: true, // 대상 덮어쓰기
preserveTimestamps: true, // 타임스탬프 유지
filter: (src, dest) => { // 필터링
return !src.includes('node_modules');
}
});
4. 여러 파일 처리
4.1 여러 파일 삭제
const fs = require('fs').promises;
async function deleteFiles(files) {
const results = await Promise.allSettled(
files.map(file => fs.unlink(file))
);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`${files[index]} 삭제 완료`);
} else {
console.log(`${files[index]} 삭제 실패:`, result.reason.message);
}
});
}
await deleteFiles(['temp1.txt', 'temp2.txt', 'temp3.txt']);
4.2 패턴으로 파일 삭제
const fs = require('fs').promises;
const path = require('path');
async function deleteByPattern(directory, pattern) {
const files = await fs.readdir(directory);
const regex = new RegExp(pattern);
const deletePromises = files
.filter(file => regex.test(file))
.map(file => fs.unlink(path.join(directory, file)));
await Promise.all(deletePromises);
}
// .tmp 파일 모두 삭제
await deleteByPattern('./temp', '\\.tmp$');
// .log 파일 모두 삭제
await deleteByPattern('./logs', '\\.log$');
4.3 여러 파일 이동
const fs = require('fs').promises;
const path = require('path');
async function moveFiles(files, destDir) {
// 대상 디렉토리 생성
await fs.mkdir(destDir, { recursive: true });
const movePromises = files.map(async (file) => {
const filename = path.basename(file);
const dest = path.join(destDir, filename);
try {
await fs.rename(file, dest);
return { file, status: 'success' };
} catch (err) {
// 다른 파일 시스템인 경우 복사 후 삭제
if (err.code === 'EXDEV') {
await fs.copyFile(file, dest);
await fs.unlink(file);
return { file, status: 'success' };
}
return { file, status: 'error', error: err };
}
});
return Promise.all(movePromises);
}
const files = ['data1.txt', 'data2.txt', 'data3.txt'];
const results = await moveFiles(files, './archive');
console.log(results);
5. 안전한 파일 작업
5.1 삭제 전 확인
const fs = require('fs').promises;
async function safeDelete(filepath) {
try {
const stats = await fs.stat(filepath);
if (!stats.isFile()) {
throw new Error('파일이 아닙니다.');
}
await fs.unlink(filepath);
return { success: true };
} catch (err) {
if (err.code === 'ENOENT') {
return { success: true, message: '이미 삭제됨' };
}
return { success: false, error: err };
}
}
5.2 백업 후 이동
const fs = require('fs').promises;
const path = require('path');
async function moveWithBackup(source, destination) {
const backupDir = './backup';
const timestamp = Date.now();
const filename = path.basename(source);
// 대상에 파일이 있으면 백업
try {
await fs.access(destination);
const backupPath = path.join(backupDir, `${timestamp}_${filename}`);
await fs.mkdir(backupDir, { recursive: true });
await fs.copyFile(destination, backupPath);
console.log(`기존 파일 백업: ${backupPath}`);
} catch (err) {
if (err.code !== 'ENOENT') throw err;
}
// 파일 이동
await fs.rename(source, destination);
console.log(`파일 이동 완료: ${source} → ${destination}`);
}
5.3 휴지통으로 이동
const fs = require('fs').promises;
const path = require('path');
async function moveToTrash(filepath) {
const trashDir = './.trash';
const timestamp = Date.now();
const filename = path.basename(filepath);
const trashPath = path.join(trashDir, `${timestamp}_${filename}`);
await fs.mkdir(trashDir, { recursive: true });
await fs.rename(filepath, trashPath);
return trashPath;
}
// 휴지통 비우기
async function emptyTrash() {
const trashDir = './.trash';
await fs.rm(trashDir, { recursive: true, force: true });
await fs.mkdir(trashDir, { recursive: true });
}
6. 실전 예시
6.1 파일 정리 유틸리티
const fs = require('fs').promises;
const path = require('path');
class FileOrganizer {
constructor(sourceDir, targetDir) {
this.sourceDir = sourceDir;
this.targetDir = targetDir;
}
async organize() {
const files = await fs.readdir(this.sourceDir);
for (const file of files) {
const sourcePath = path.join(this.sourceDir, file);
const stats = await fs.stat(sourcePath);
if (!stats.isFile()) continue;
const ext = path.extname(file).slice(1).toLowerCase() || 'other';
const targetFolder = path.join(this.targetDir, ext);
await fs.mkdir(targetFolder, { recursive: true });
await fs.rename(sourcePath, path.join(targetFolder, file));
console.log(`${file} → ${ext}/`);
}
}
async cleanup(days) {
const cutoff = Date.now() - (days * 24 * 60 * 60 * 1000);
const files = await fs.readdir(this.sourceDir);
for (const file of files) {
const filepath = path.join(this.sourceDir, file);
const stats = await fs.stat(filepath);
if (stats.mtimeMs < cutoff) {
await fs.unlink(filepath);
console.log(`삭제됨: ${file}`);
}
}
}
}
const organizer = new FileOrganizer('./downloads', './organized');
await organizer.organize();
6.2 임시 파일 관리자
const fs = require('fs').promises;
const path = require('path');
const os = require('os');
class TempFileManager {
constructor() {
this.tempDir = path.join(os.tmpdir(), 'myapp');
this.files = new Set();
}
async init() {
await fs.mkdir(this.tempDir, { recursive: true });
}
async create(prefix = 'tmp') {
const filename = `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2)}`;
const filepath = path.join(this.tempDir, filename);
await fs.writeFile(filepath, '');
this.files.add(filepath);
return filepath;
}
async cleanup() {
for (const file of this.files) {
try {
await fs.unlink(file);
} catch (err) {
// 이미 삭제된 경우 무시
}
}
this.files.clear();
}
async cleanupAll() {
await fs.rm(this.tempDir, { recursive: true, force: true });
await this.init();
this.files.clear();
}
}
const temp = new TempFileManager();
await temp.init();
const tempFile = await temp.create('session');
// 작업 수행
await temp.cleanup();
결론
Node.js에서 파일 삭제는 unlink, rm 메서드를 사용하고, 이동은 rename 메서드를 사용합니다. 다른 파일 시스템 간 이동 시에는 copyFile로 복사 후 unlink로 삭제해야 합니다. Node.js 14.14+의 rm과 16.7+의 cp 메서드는 재귀 옵션을 지원하여 디렉토리 작업을 간편하게 합니다. 프로덕션 환경에서는 백업, 휴지통 기능을 구현하여 안전한 파일 관리를 하는 것이 좋습니다.
728x90
반응형
'Node.js' 카테고리의 다른 글
| Node.js의 파일 읽기와 쓰기 (0) | 2026.02.28 |
|---|---|
| Node.js의 이벤트 에미터(EventEmitter) 사용법 (0) | 2026.02.25 |
| Node.js의 타이머 함수(Timer Functions) (0) | 2026.02.25 |
| Node.js의 콘솔 객체(console object) (0) | 2026.02.25 |
| Node.js의 프로세스 객체(process object) (0) | 2026.02.25 |