Flutter Pub Collection
[ path_provider ]
Flutter 패키지

소개

파일 시스템의 일반적인 위치에 접근하기 위한 플랫폼별 경로 제공 패키지

설치

pub.dev: https://pub.dev/packages/path_provider

$ flutter pub add path_provider
import 'package:path_provider/path_provider.dart';
import 'dart:io';

1. 임시 디렉토리

시스템이 언제든 삭제할 수 있는 임시 파일용. 캐시와 유사.

final dir = await getTemporaryDirectory();
final file = File('${dir.path}/temp.txt');

2. 문서 디렉토리

사용자 데이터 저장. 앱 삭제 시까지 유지. iOS는 iCloud 백업.

final dir = await getApplicationDocumentsDirectory();
final file = File('${dir.path}/user_data.json');

3. 지원 디렉토리

앱 설정 및 내부 파일 저장. iCloud 백업 제외.

final dir = await getApplicationSupportDirectory();
final file = File('${dir.path}/config.txt');

4. 캐시 디렉토리

재생성 가능한 데이터. 시스템이 자동으로 정리 가능.

final dir = await getApplicationCacheDirectory();
final file = File('${dir.path}/cached_image.jpg');

5. 실전 예제: 설정 저장

JSON 형태로 앱 설정 저장/로드.

// 저장
final dir = await getApplicationSupportDirectory();
final file = File('${dir.path}/settings.json');
await file.writeAsString(jsonEncode(settings));

// 로드
final content = await file.readAsString();
final settings = jsonDecode(content);

6. 실전 예제: 이미지 캐시

다운로드한 이미지를 캐시에 저장하여 재사용.

final dir = await getApplicationCacheDirectory();
final filename = url.split('/').last;
final file = File('${dir.path}/$filename');
await file.writeAsBytes(imageBytes);

7. 플랫폼별 차이점

iOS와 Android는 파일 시스템 구조가 다릅니다. 모든 메서드가 모든 플랫폼에서 지원되지 않습니다.

// Android 전용 - iOS에서는 null 반환
final androidDir = await getExternalStorageDirectory();
if (androidDir != null) {
  // Android 전용 로직
}

// iOS/Android 공통
final documentsDir = await getApplicationDocumentsDirectory();

8. Android 권한 설정

외부 저장소 접근 시 AndroidManifest.xml에 권한 추가 필요.

<manifest xmlns:android="...">
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

  <!-- Android 13+ 미디어 접근 -->
  <uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
</manifest>

9. 외부 저장소 접근 (Android)

Android에서만 사용 가능. iOS에서는 null 반환하므로 체크 필수.

Future<String?> getExternalPath() async {
  if (Platform.isAndroid) {
    final dir = await getExternalStorageDirectory();
    return dir?.path;
  }
  // iOS는 getApplicationDocumentsDirectory 사용
  final dir = await getApplicationDocumentsDirectory();
  return dir.path;
}

10. 파일 경로 결합

path 패키지와 함께 사용하여 안전한 경로 생성.

import 'package:path/path.dart' as p;

final dir = await getApplicationDocumentsDirectory();
final filePath = p.join(dir.path, 'my_folder', 'data.json');
final file = File(filePath);

11. 디렉토리 존재 확인 및 생성

파일 저장 전 디렉토리 존재 확인 및 생성.

final dir = await getApplicationDocumentsDirectory();
final myDir = Directory('${dir.path}/my_folder');

if (!await myDir.exists()) {
  await myDir.create(recursive: true);
}

final file = File('${myDir.path}/data.txt');
await file.writeAsString('content');

12. 파일 나열 및 검색

디렉토리 내 모든 파일 나열 및 필터링.

final dir = await getApplicationDocumentsDirectory();
final files = dir.listSync();

// 특정 확장자 필터링
final jsonFiles = files
  .whereType<File>()
  .where((f) => f.path.endsWith('.json'))
  .toList();

13. 캐시 크기 관리

캐시 디렉토리 크기 계산 및 정리.

Future<int> getCacheSize() async {
  final dir = await getApplicationCacheDirectory();
  int totalSize = 0;

  await for (var entity in dir.list(recursive: true)) {
    if (entity is File) {
      totalSize += await entity.length();
    }
  }
  return totalSize;
}

Future<void> clearCache() async {
  final dir = await getApplicationCacheDirectory();
  await dir.delete(recursive: true);
  await dir.create(); // 디렉토리 재생성
}

14. 임시 파일 자동 정리

임시 디렉토리는 시스템이 자동 정리. 중요 데이터는 documents에 저장.

// ❌ 임시 디렉토리에 중요 데이터 저장 금지
final tempDir = await getTemporaryDirectory();
// 시스템이 언제든 삭제 가능

// ✅ 중요 데이터는 documents에 저장
final docsDir = await getApplicationDocumentsDirectory();
final file = File('${docsDir.path}/important.json');
await file.writeAsString(jsonEncode(data));

15. 테스트 방법

PathProviderPlatform을 mock하여 테스트.

// test/path_provider_test.dart
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';

class MockPathProvider extends PathProviderPlatform {
  @override
  Future<String?> getApplicationDocumentsPath() async {
    return '/mock/documents';
  }
}

void main() {
  PathProviderPlatform.instance = MockPathProvider();
  // 테스트 실행
}

16. 주의사항

안전한 파일 처리를 위한 핵심 가이드라인.

// ✅ 플랫폼 체크
if (Platform.isAndroid) {
  final dir = await getExternalStorageDirectory();
}

// ✅ 에러 처리
try {
  final file = File('${dir.path}/data.json');
  await file.writeAsString(json);
} catch (e) {
  print('파일 저장 실패: $e');
}

// ✅ 경로 결합 시 path 패키지 사용
// ❌ '${dir.path}/folder/file.txt' 대신
// ✅ p.join(dir.path, 'folder', 'file.txt')

패키지 정보

pub.dev: https://pub.dev/packages/path_provider

version: 2.1.5

likes: 5.4k

Publisher: flutter.dev

Platforms: Android, iOS, Linux, macOS, Windows