반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 커스텀상태
- theming
- Compose
- 알게되는
- mockito
- 코틀린
- 디자인패턴
- kotlin강좌
- android
- Gradle
- Rxjava
- viewmodel
- g 단위테스트
- 병렬프로그래밍
- 병럴프로그래밍
- 테스트
- 회고
- 안드로이드스튜디오
- 안드로이드강좌
- 책
- 알고리즘
- 자바
- Coroutine
- Kotlin
- 글또
- ReactiveProgramming
- k8s
- 안드로이드
- 코루틴
- 스레드
Archives
- Today
- Total
선생님, 개발을 잘하고 싶어요.
[안드로이드 잡학] File 저장하기 (internal , external storage) 본문
파일 저장소 구분
internal: 항상 접근 가능, 파일을 저장한 앱에서만 접근 가능, 앱 제거시 함께 사라짐
external: removable한 저장소 (usb, disk 등은 항상 제거될 수 있다), 어디서든 접근 가능, 앱 제거해도 그대로 남아있음.
주의 사항) app-specific external은 그냥 외부 disk (sdcard) 등에 저장될 뿐 앱과 함께 제거되고 접근 가능한 속성을 그대로 가진다.
Internal 저장소 사용 예시
class InternalFileStorageUseCase {
private lateinit var context: Context
// 내부 저장소에 저장된 파일에 접근하기
fun accessStoredFile(): File {
val dir = context.filesDir
val filename = "sample.txt"
val file = File(dir, filename)
return file
}
// Stream 사용해서 파일 저장하기
fun storeFileUsingStream() {
val filename = "sample.txt"
val fileContent = "Hello World!"
// API 24 이상에서, MODE_PRIVATE 사용 안하면, SecurityException 발생
context.openFileOutput(filename, Context.MODE_PRIVATE).use {
it.write(fileContent.toByteArray())
}
}
// Stream 사용해서 파일 접근하기
fun accessFileUsingStream() {
val filename = "sample.txt"
context.openFileInput(filename).bufferedReader().useLines { lines ->
lines.fold("") { some, text ->
"$some\n$text"
}
}
}
// 파일 리스트 받아오기
fun viewListOfFiles() {
var files: Array<String> = context.fileList()
}
// 폴더 만들기
fun createNestedDir() {
val dirName = "sub"
context.getDir(dirName, Context.MODE_PRIVATE)
}
// 캐시 파일 만들기
fun createCacheFile() {
val cacheDir = context.cacheDir
val filename = "temp.jpg"
File.createTempFile(filename, null, cacheDir)
}
// 캐시 파일 접근하기, 단 캐시 파일의 경우 안드로이드가 임의로 지워버릴 수 있음.
fun accessCacheFile(): File {
val filename = "temp.jpg"
val cacheFile = File(context.cacheDir, filename)
return cacheFile
}
// 캐시 파일 제거하기
// 안드로이드가 캐시 파일을 제거를 보장하지는 않음. 적절한 처리할 것
fun removeCacheFile() {
val cacheFile = accessCacheFile()
// case 1
cacheFile.delete()
// case 2
context.deleteFile(cacheFile.name)
}
}
External 저장소 사용 예시
// 앱 특화된 external 저장소로, API 19 이상부턴 별다른 권한 없이 접근이 가능하다.
// 앱을 제거할 때 함께 제거된다.
// 항상 접근이 보장되는게 아니기 때문에, 앱의 메인 기능을 이 파일에 의존하면 안된다.
// API 28 이하에서는 적절한 권한만 있으면, 다른 앱의 external 영역에 접근할 수 있다.
// API 29 이상에서는 scoped storage로 관리하면 된다, scoped access를 허용하면, 다른 앱의 external 파일에 접근 못함.
class ExternalFileStorageUseCase {
private lateinit var context: Context
// external은 항상 접근가능하지 않다. (sd card, usb를 생각해봐라 사용자가 마음대로 뽑아버릴 수 있다.)
// 쓰기 가능한 상태인지 체크
fun isExternalStorageWritable(): Boolean {
return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
}
// 읽기 가능한 상태인지 체크
fun isExternalStorageReadable(): Boolean {
return Environment.getExternalStorageState() in
setOf(Environment.MEDIA_MOUNTED, Environment.MEDIA_MOUNTED_READ_ONLY)
}
// 여러 볼륨 중에 고르기
// API 18 이하에서는 하나만 있다.
fun selectPhysicalStorageLocation(): File {
val externalStorageVolumes: Array<out File> =
ContextCompat.getExternalFilesDirs(context, null)
val primaryExternalStorage = externalStorageVolumes[0]
return primaryExternalStorage
}
// app-specific 외부 저장소에 파일 접근하기
fun accessFile(): File {
val externalDir = context.getExternalFilesDir(null)
val filename = "sample.txt"
val file = File(externalDir, filename)
return file
}
// API 30 이상부터 앱에서 external storage에 본인 소유 directory 못만든다.
fun createCacheFile(): File? {
if (isExternalStorageWritable()) {
val externalCacheDir = context.externalCacheDir
val filename = "temp.jpg"
val file = File(externalCacheDir, filename)
return file
} else {
return null
}
}
}
참고 자료
Data and File Storage Overview : 저장할 데이터의 속성에 따라서 무슨 API를 봐야할 지 table 형태로 정리된 자료, 데이터 저장소 작업이 필요할 때 항상 처음으로 참고할 웹사이트
Raywenderlich Saving Data On Android : 안드로이드 데이터 저장 관련 시리즈 중 File 관련 내용만 발췌, 전체 내용을 보고 한번 자신만의 UseCase를 정리하면 요긴하게 사용할 수 있을 것 같음.
Access app-sepcific files : 앱에서만 접근할 수 있는 (context에서 제공하는) 파일 저장소 API, 사용법을 보고 정리하면 좋을 듯
'개발 > android 개발' 카테고리의 다른 글
[Custom View] 안드로이드 커스텀 뷰, 커스텀 상태 state 선언하고 사용하기 (1) | 2022.06.03 |
---|---|
[OAuth] 카카오 로그인 안드로이드 kotlin, coroutine 구현 가이드, 플랫폼 설정 부터 coroutine utility 까지 (5) | 2022.06.03 |
[Compose] 소프트 키보드 닫기 (0) | 2022.02.27 |
[Android] Styling, Style과 Theme 바로알기 좋은 자료 (0) | 2022.01.23 |
URL 구조와 OkHttp3를 이용한 URL 생성 및 파싱 (0) | 2022.01.16 |
Comments