Flutter 저장소 폴더 구조

Chance·2022년 9월 22일
0

안드로이드

path_provider package , dart:io library(File, Directory)

내부 저장소 (Internal)

  • 모든 안드로이드 기기에 포함되어 있는 저장 공간이-다.
  • 앱 설치 시 해당 앱을 위한 별도의 저장공간을 만든다.
  • 앱 삭제 시 같이 삭제된다.
  • 데이터 저장 경로
    /data/user/0/패키지 이름

외부 저장소 (External)

  • 앱 삭제 여부와 관계없이 영구적으로 파일을 저장한다.
  • Manifest에서 권한을 부여받아야 한다.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  • 데이터 저장 경로
    /storage/emulated/0/Android/data/패키지 이름/files

path_provider 라이브러리

일반적으로 플러터에서 가장 많이 사용하는 저장 위치경로 들을 얻을 수 있는 패키지

  • Temporary directory: 캐쉬같이 임시로 데이터를 저장하는 공간이고 언제든지 삭제될 수 있다.
    iOS 의 NSCachesDirectory와 Android 의 getCacheDir() 의 값에 해당하는 위치이다.

  • Documents directory: 해당 앱만의 저장공간이며 앱이 삭제되면 없어진다.
    iOS 의 NSDocumentDirectory 와 Android 의 AppData 값에 해당한다.

functions

아래의 함수들을 통해 일반적인 앱이 접근하여 사용하는 저장공간에 해당하는 파일 시스템상의 위치 정보를 얻을 수 있다.

getApplicationDocumentsDirectory()

  • /data/user/0/패키지명/app_flutter

getApplicationSupportDirectory()

  • /data/user/0/패키지명/files

getExternalCacheDirectories()

  • '/storage/SDcard/Android/data/패키지명/cache'

getExternalStorageDirectories({StorageDirectory type })

  • '/storage/SDcard/Android/data/패키지명/files'

getExternalStorageDirectory()

  • /storage/emulated/0/Android/data/패키지명/files

getTemporaryDirectory()

  • '/data/user/0/패키지명/cache'

getApplication, getExternal차이점
= 사용자가 접근가능한 폴더에 접근 유무

Directory('path')

  • 해당 앱과 사용자가 엑세스 할 수 있는 커스텀 경로
  • 파일 입출력 permission 필요
// dir생성
var directory = await Directory('path').create(recursive: true);
// system디렉토리 항목 나열
var systemTempDir = Directory.systemTemp;
// dir존재 여부
final myDir = Directory('dir');
var isThere = await myDir.exists();

external_path 라이브러리

외부저장소에 접근할 수 있는 경로를 반환해줌

function
ExternalPath.getExternalStorageDirectories()

  • [ /storage/emulated/0, /storage/SDCard이름 ]

getExternalStoragePublicDirectory(공용저장소)

  • ExternalPath.DIRECTORY_MUSIC
  • ExternalPath.DIRECTORY_PODCASTS
  • ExternalPath.DIRECTORY_RINGTONES
  • ExternalPath.DIRECTORY_ALARMS
  • ExternalPath.DIRECTORY_NOTIFICATIONS
  • ExternalPath.DIRECTORY_PICTURES
  • ExternalPath.DIRECTORY_MOVIES
  • ExternalPath.DIRECTORY_DOWNLOADS
  • ExternalPath.DIRECTORY_DCIM
  • ExternalPath.DIRECTORY_DOCUMENTS
  • ExternalPath.DIRECTORY_SCREENSHOTS
  • ExternalPath.DIRECTORY_AUDIOBOOKS

권한 요청 (Permission)

Android 11 (API 30) 부터 외부저장소 앱 및 사용자 데이터를 보호하기 위해 범위 지정 저장소 도입
(android 11에서 기존 권한(android.permission.WRITE_EXTERNAL_STORAGE) 무시됨
출처: https://devmason.tistory.com/344 [With IT:티스토리]

Android 10 (API 29)를 타겟팅 하는 앱에서는 requestLegacyExternalStorage를 요청하여 범위 지정 저장소와 관련된 사항을 해제할 수 있엇지만, Android 11부터 requestLegacyExternalStorage는 무시됨.

따라서, 새로운 파일 관리를 위한 파일 엑세스 권한 요청이 필요함.
= MANAGE_EXTERNAL_STORAGE
= 앱에 대한 모든 파일 관리 허용 옵션

// 저장공간 permission 허용
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />

이후, permission_handler 라이브러리를 사용해서 권한 요청

    // android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    PermissionStatus status = await Permission.manageExternalStorage.request();

    final dir = await ExternalPath.getExternalStorageDirectories();

    // 디렉터리 경로 가져온 후 하위 디렉토리 생성
    Directory path_dir = await Directory('${dir[0]}/').create(recursive: true);
    // 위에서 생성한 디렉토리에 파일 생성하고 리턴
    print('경로 : ${path_dir.path}');

    if (status.isDenied) {
      print('권한요청 실패');
    } else {
      print('권한요청 성공');
    }

storage permission 관련 참고 링크
함수 별 경로
permission 관련 - 1
permission 관련 - 2

디바이스

backup

  • 디바이스 메모리 -> copy -> 내장 메모리

restore

  • 내장 메모리 -> copy -> 디바이스 메모리

Device Explorer

내부 메모리 : 실행 중인 앱의 메모리에 저장되어 있는 것

data/data/패키지명

내부 저장소 : 디바이스 기기에서 기본적으로 제공되는 저장소 공간

storage/self/primary/

외부 저장소 : 디바이스 기기 이외에 저장소 (sd카드 등등)

storage/'SD카드명'/

출처
https://iosroid.tistory.com/45 [조용한 담장:티스토리]
https://ksrapp.tistory.com/6

Image 각 자료형으로 바꾸기

https://byunpa.tistory.com/187
https://m.blog.naver.com/heennavi1004/222390438020

Uri를 filepath로 바꾸는 방법

  • uri_to_file라이브러리 사용

이미지 별 경로 찾기

toFile(url) : /data/data/패키지명/files/uri_to_file/파일명
image.picker : /data/user/0/패키지명/cache/파일명
getTemporaryDirectory : /data/user/0/패키지명/cache/파일명

Uri(Uint8List capture) -> filepath

uri_to_file 라이브러리 사용
Uri uri = Uri.parse(result['filePath']);
// uri : content://media/external/images/media/1599

File file = await toFile(uri.toString());
// File: '/data/data/패키지명/files/uri_to_file/파일명'

= getTemporaryDirectory로 cache에 파일 저장 후 사용

공유 shape 사이즈 조절

final box = context.findRenderObject() as RenderBox?;
sharePositionOrigin: box!.localToGloal(Offset.zero) & box.size

  • iPad전용 공유 shape가 화면 중앙에 오도록 표시
  • 안드로이드는 X

IOS


ios개발자 페이지 (폴더 구조) 참고
https://developer.apple.com/documentation/foundation/nssearchpathdirectory/nscachesdirectory
stackoverflow ios path 참고
https://stackoverflow.com/questions/59501445/flutter-how-to-save-a-file-on-ios

pathprovider를 통해서 경로에 접근할 때 사용하는 함수
ex)getApplicationDocumentsDirectory()
를 사용하면 플러그인에서 각 기기에 맞는 경로로 접근해서 파일을 엑세스한다.
getApplicationDocumentsDirectory를 사용하면
IOS = NSDocumentDirectory로 이동하고
android = /data/user/0/패키지 이름/app_flutter
_

IOS File Structure

ios는 자체 sandbox디렉토리 내부로 제한됨.

  1. Bundle Container
  • 앱의 번들을 보유
  1. Data Container
  • 앱과 사용자 모두에 대한 데이터를 보유
  • 앱이 데이터를 정렬하고 구성하는데 사용할 수 있는 여러 하위 디렉터리로 나뉜다.
  1. iCloud Container

앱은 일반적으로 컨테이너 디렉터리 외부에 있는 파일에 엑세스하거나 파일을 생성할 수 없다.
= path_provider에서 getExternal을 사용할 수 없다.

예외적으로 앱이 공용 시스템 인터페이스를 사용하여 사용자의 연락처, 음악같은 항목에 엑세스하는 경우

  • 시스템 프레임워크는 도우미 앱을 사용하여 적절한 데이터 저장소를 읽거나 수정할 수 있다.

Data Container

Documents/

이 디렉토리를 사용하여 사용자 생성 콘텐츠를 저장합니다. 이 디렉토리의 내용은 파일 공유를 통해 사용자가 사용할 수 있습니다. 따라서 이 디렉토리에는 사용자에게 노출하려는 파일만 포함되어야 합니다.

이 디렉토리의 내용은 iTunes 및 iCloud에 의해 백업됩니다.

Documents/Inbox

앱은 이 디렉터리의 파일을 읽고 삭제할 수 있지만 새 파일을 만들거나 기존 파일에 쓸 수는 없습니다. 사용자가 이 디렉터리의 파일을 편집하려고 하면 앱은 변경하기 전에 디렉터리 밖으로 파일을 자동으로 이동해야 합니다.

Library/

Library사용자에게 노출하지 않으려는 파일에는 하위 디렉토리를 사용하십시오. 앱은 사용자 데이터 파일에 이러한 디렉터리를 사용해서는 안 됩니다.

ios File System 참고 https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html

ios 외부 저장소에 있는 파일에 엑세스 하려면?

path_provider
getApplicationDocumentsDirectory()
= 사용자에게 모든 파일 표시
getApplicationSupportDirectory()
= 사용자에게 파일을 보여주지 않음

stackoverflow참고
https://stackoverflow.com/questions/55220612/how-to-save-a-text-file-in-external-storage-in-ios-using-flutter

1개의 댓글

comment-user-thumbnail
2023년 5월 21일

감사합니다. 덕분에 궁금했던 내용을 한번에 알아갑니다 ^^

답글 달기