소소한 일상과 잡다한 정보

IT/Dart

Dart_11일차 : 파일 및 디렉터리 관리 (File & Directory Handling)

pandada 2025. 3. 10. 15:21
반응형

 

 이번에는 Dart에서 파일과 디렉터리를 관리하는 방법을 확인해보자.

  • 디렉터리 생성 및 삭제 (Directory)
  • 디렉터리 내 파일 및 폴더 리스트 출력
  • 파일 복사, 이동, 삭제 (copy(), rename(), delete())
  • 비동기(Async) 방식으로 안전하게 파일 및 폴더 관리

1. 디렉터리 생성 및 삭제 ( Directory )

 Dart의 dart:io 라이브러리를 사용하면 디렉터리를 생성하거나 삭제할 수 있다.

 ✔️ 디렉터리 생성 ( create() )

import 'dart:io';

void main() async {
  Directory dir = Directory('test_directory');

  if (!await dir.exists()) {
    await dir.create();
    print("📂 디렉터리 생성 완료: ${dir.path}");
  } else {
    print("✅ 디렉터리가 이미 존재합니다.");
  }
}
  • Directory('경로') → 디렉터리 객체 생성
  • exists() → 디렉터리 존재 여부 확인
  • create() → 디렉터리 생성

 ✔️ 디렉터리 삭제 ( delete() )

import 'dart:io';

void main() async {
  Directory dir = Directory('test_directory');

  if (await dir.exists()) {
    await dir.delete(recursive: true); // 내부 파일까지 삭제
    print("🗑 디렉터리 삭제 완료");
  } else {
    print("⚠️ 삭제할 디렉터리가 없습니다.");
  }
}
  • delete(recursive: true) 디렉터리 안에 파일이 있어도 강제 삭제

📌 delete()의 동작 요약

옵션 설명
delete() (기본값) 비어있는 파일/디렉터리만 삭제 가능
delete(recursive: false) 비어있는 디렉터리만 삭제 가능 (파일이 있으면 에러)
delete(recursive: true) 디렉터리 내부 파일 및 하위 폴더까지 삭제 가능

🔹 파일을 삭제할 때는 delete()만 사용하면 됨 (파일은 recursive 옵션이 필요 없음)
🔹 디렉터리를 삭제할 때 recursive: true를 사용하면 내부 파일까지 전부 삭제됨
🔹 비어 있는 디렉터리만 삭제하고 싶다면 recursive: false(기본값) 사용


2. 디렉터리 내 파일 및 폴더 리스트 출력

import 'dart:io';

void main() async {
  Directory dir = Directory('test_directory');

  if (await dir.exists()) {
    List<FileSystemEntity> contents = dir.listSync(); // 동기 방식으로 목록 가져오기

    print("📂 디렉터리 내용:");
    for (var entity in contents) {
      print(entity.path);
    }
  } else {
    print("⚠️ 디렉터리가 존재하지 않습니다.");
  }
}
  • listSync() → 디렉터리 안의 파일 및 폴더 목록 가져오기

3. 파일 복사, 이동, 삭제

 여러 줄 데이터를 저장하고 읽을 수도 있다.

 ✔️ 파일 복사 ( copy() )

import 'dart:io';

void main() async {
  File originalFile = File('test.txt');
  File copiedFile = File('copy_test.txt');

  if (await originalFile.exists()) {
    await originalFile.copy(copiedFile.path);
    print("📄 파일 복사 완료: ${copiedFile.path}");
  } else {
    print("⚠️ 원본 파일이 존재하지 않습니다.");
  }
}
  • copy(경로) → 파일을 복사하여 새로운 파일 생성

 ✔️ 파일 이름 변경 ( rename() )

import 'dart:io';

void main() async {
  File file = File('test.txt');

  if (await file.exists()) {
    await file.rename('moved_test.txt');
    print("🚚 파일 이동 완료");
  } else {
    print("⚠️ 이동할 파일이 존재하지 않습니다.");
  }
}
  • rename(새 경로) → 기존 파일을 새로운 경로로 이동

 ✔️ 파일 이동 ( rename() )

import 'dart:io';

void main() async {
  File file = File('test.txt'); // 기존 파일

  if (await file.exists()) {
    await file.rename('new_directory/test.txt'); // 다른 폴더로 이동
    print("🚚 파일 이동 완료: test.txt → new_directory/test.txt");
  } else {
    print("⚠️ 이동할 파일이 존재하지 않습니다.");
  }
}
  • 파일 이름은 그대로 유지되지만, 새로운 디렉터리로 이동
  • 폴더( new_directory/ )가 미리 존재해야 오류 없이 이동 가능
  • 파일을 이동하면서 이름도 변경할 수 있음 ( new_directory/new_name.txt )
메서드 설명
rename('새이름.txt') 같은 폴더 내에서 파일 이름 변경
rename('새디렉터리/파일이름.txt') 파일을 다른 디렉터리로 이동 (이름 변경 가능)

 

✔️ 파일 이동 + 이름 변경

import 'dart:io';

void main() async {
  File file = File('test.txt'); // 기존 파일

  if (await file.exists()) {
    await file.rename('new_directory/new_test.txt'); // 다른 폴더로 이동 + 이름 변경
    print("🚚 파일 이동 완료: test.txt → new_directory/new_test.txt");
  } else {
    print("⚠️ 이동할 파일이 존재하지 않습니다.");
  }
}
  •  test.txtnew_directory/new_test.txt 로 이동하면서 이름도 변경 가능
  • 이동할 디렉터리( new_directory/ )가 미리 존재해야 오류 없음
  • 만약 new_directory/ 가 없으면 createSync() 로 먼저 만들어야 함

 

 ✔️ 파일 삭제 ( delete() )

import 'dart:io';

void main() async {
  File file = File('test.txt');

  if (await file.exists()) {
    await file.delete();
    print("🗑 파일 삭제 완료");
  } else {
    print("⚠️ 삭제할 파일이 없습니다.");
  }
}
  • delete() → 파일 삭제

 

📌 Dart에서 delete()는 휴지통 이동이 아니라 "완전 삭제"

  • Dart의 delete()는 운영체제(OS)에서 제공하는 휴지통(Trash, Recycle Bin)으로 이동하는 기능이 없음.
  • delete()를 실행하면 즉시 영구 삭제되며 복구할 수 없음.
  • 하지만 직접 휴지통으로 이동하는 방법을 구현할 수 있음!

✅ 해결 방법: 휴지통 폴더로 이동하는 방식으로 우회

Dart에서 운영체제(OS) 별로 휴지통으로 이동하는 API가 없기 때문에, 휴지통을 흉내내는 폴더( Trash/ , RecycleBin/ )를 만들어 이동하는 방식으로 해결할 수 있다.

✔️ 휴지통 폴더( trash/ )로 파일 이동

import 'dart:io';

void main() async {
  File file = File('test.txt'); // 삭제할 파일
  Directory trashDir = Directory('trash'); // 휴지통 폴더

  if (await file.exists()) {
    // 휴지통 폴더가 없으면 생성
    if (!await trashDir.exists()) {
      await trashDir.create(recursive: true);
    }

    // 파일을 휴지통 폴더로 이동
    String newFilePath = 'trash/${file.uri.pathSegments.last}';
    await file.rename(newFilePath);

    print("🗑 파일이 휴지통으로 이동됨: $newFilePath");
  } else {
    print("⚠️ 삭제할 파일이 존재하지 않습니다.");
  }
}
  • Directory('trash')휴지통 역할을 하는 폴더를 생성
  • rename('trash/파일명')파일을 휴지통 폴더로 이동 (완전 삭제 X)
반응형

✔️ 테스트 예제 코드 1

 위에서 진행했던 내용을 토대로 충분한 실습을 진행한 후, 테스트 예제를 진행해보도록 하자.

 1. 새로운 디렉터리를 생성하고, 디렉터리 안에 파일을 하나 생성하는 프로그램

 2. 새로운 디렉터리(my_directory/)를 생성

 3. 디렉터리 안에 파일(my_directory/my_file.txt)을 생성하고 내용 작성

 4. 디렉터리가 이미 있으면 생성하지 않고 바로 파일 생성

import 'dart:io';

void main() async {
  String dirPath = 'my_directory'; // 생성할 디렉터리 경로
  String filePath = '$dirPath/my_file.txt'; // 생성할 파일 경로

  Directory dir = Directory(dirPath);

  // 디렉터리가 없으면 생성
  if (!await dir.exists()) {
    await dir.create(recursive: true);
    print("📂 디렉터리 생성 완료: $dirPath");
  } else {
    print("✅ 디렉터리가 이미 존재합니다.");
  }

  // 파일 생성 및 내용 쓰기
  File file = File(filePath);
  await file.writeAsString("이 파일은 Dart에서 생성되었습니다.");

  print("📄 파일 생성 완료: $filePath");
}
  •  Directory(dirPath).exists() → 디렉터리 존재 여부 확인
  •  create(recursive: true) → 디렉터리가 없으면 생성 (recursive: true로 하위 폴더까지 생성 가능)
  •  File(filePath).writeAsString("내용") → 파일을 생성하고 내용 작성

 

✔️ 테스트 예제 코드 2

 1. 디렉터리 내 모든 파일 목록을 출력하는 프로그램

 2. 주어진 디렉터리(my_directory/)의 모든 파일과 폴더 목록 출력
 3. 파일과 폴더를 구분하여 출력 (isFile, isDirectory)
 4. 디렉터리가 없으면 자동 생성 후 안내 메시지 출력

 5. Dart의 path 패키지를 사용하지 않고  replaceFirst()  사용 ( 디렉터리 안의 디렉터리의 리스트 path를 구하기 위해 )
 6. 파일이 존재하지 않을 때 새 파일을 생성하도록 수정 가능

import 'dart:io';

void main() async {
  String dirPath = 'test_directory';
  Directory dir = Directory(dirPath);

  if (!await dir.exists()) {
    await dir.create(recursive: true);
    print("🆕 디렉터리가 없어서 새로 생성되었습니다: $dirPath");
  }

  print("📂 '$dirPath' 디렉터리 내용:");

  await for (var entity in dir.list(recursive: true, followLinks: false)) {
    String relativePath = entity.path.replaceFirst('$dirPath/', ''); // 최상위 폴더 제거

    if (entity is File) {
      print("📄 파일: $relativePath");
    } else if (entity is Directory) {
      print("📁 폴더: $relativePath");
    }
  }
}
  •  Directory(dirPath).exists() → 디렉터리 존재 여부 확인
  •  create(recursive: true) → 디렉터리가 없으면 생성
  •  if (entity is File) {...} → 파일이면 "📄 파일" 출력
  •  if (entity is Directory) {...} → 폴더이면 "📁 폴더" 출력

 

✔️ 테스트 예제 코드 3

 1. 특정 파일을 다른 디렉터리로 이동하는 프로그램

 2. 사용자가 지정한 파일을 새로운 디렉터리로 이동
 3. 이동할 디렉터리가 없으면 자동 생성
 4. 파일이 존재하지 않으면 오류 메시지 출력

import 'dart:io';

void main() async {
  String sourceFilePath = 'test.txt'; // 이동할 파일 경로
  String targetDirectoryPath = 'backup_directory'; // 이동할 디렉터리
  String targetFilePath = '$targetDirectoryPath/test.txt'; // 이동 후 파일 경로

  File file = File(sourceFilePath);
  Directory targetDirectory = Directory(targetDirectoryPath);

  // 파일이 존재하는지 확인
  if (!await file.exists()) {
    print("⚠️ 이동할 파일이 존재하지 않습니다: $sourceFilePath");
    return;
  }

  // 이동할 디렉터리가 없으면 생성
  if (!await targetDirectory.exists()) {
    await targetDirectory.create(recursive: true);
    print("📂 이동할 디렉터리 생성 완료: $targetDirectoryPath");
  }

  // 파일 이동
  await file.rename(targetFilePath);
  print("🚚 파일 이동 완료: $sourceFilePath → $targetFilePath");
}
  •  File(sourceFilePath).exists() → 이동할 파일이 존재하는지 확인
  •  Directory(targetDirectoryPath).exists() → 이동할 디렉터리가 존재하는지 확인
  •  create(recursive: true) → 디렉터리가 없으면 자동 생성
  •  rename(targetFilePath) → 파일을 지정한 폴더로 이동

 


 이렇게 파일 및 디렉터리 관리 (File & Directory Handling) 활용에 대해서 알아보았다. 추가 적인 내용이 필요한 경우에는 댓글을 요청드리고, 틀린 부분이 있다면 이것 또한 댓글로 알려주시면 수정하도록 하겠습니다!


 

반응형