[Android] 파일 입출력
Intro
🙋♀️ 이번 포스팅에서는 파일 입출력에 관해 작성해보고자 한다!
안드로이드 데이터 저장소는 크게 2가지로 나뉜다.
1. 내부 저장소: 애플리케이션을 통해서만 접근 가능하다.
- 용량이 작다.
2. 외부 저장소: 단말기 내부 고유 영역이 존재해 모든 애플리케이션에서 접근 가능하다.
- 용량이 크다.
- scoped storage 정책
👩 그렇다면 scoped storage 정책에 대해서 조금 더 자세히 살펴보자!
🙋♀️ scoped storage 정책
- 앱 데이터 폴더
- 읽고 쓰기 권한 필요하지 않다.
- 해당 app에서만 접근이 가능하다.
- app 삭제 시, 함께 삭제된다.
-
미디어 파일들: 사진, 동영상, 음원 파일 저장소
- 공용 파일들
- Downloads 폴더에 저장된다.
- 모든 app에서 접근이 가능하다. (파일 관리자 어플을 통해 사용자가 선택한 파일이 대상!)
이번 포스팅에서는 내부 저장소, 앱 데이터 폴더, 공용 파일 폴더 세가지를 살펴볼 것이다.
🙋♀️내부 저장소
- openFileOutput, openFileInput
- in/output stream을 얻어와 사용한다.
1. openFileOutput을 통해 내부 저장소에 데이터 저장!
val fos = openFileOutput("data1.dat", Context.MODE_PRIVATE)
val dos = DataOutputStream
dos.writeInt(10)
dos.writeBoolean(true)
dos.writeUTF("test1")
dos.flush()
dos.close()
- MODE_PRIVATE: 덮어 씌우기
- MODE_APPEND: 이어서 쓰기
2. openFileInput을 통해 내부 저장소 데이터 읽기!
val fis = openFileInput("data1.dat")
val dis = DataInputStream(fis)
val data1 = dis.readInt()
val data3 = dis.readBoolean()
val data4 = dis.readUTF()
dis.close()
🙋♀️외부 저장소: 앱 데이터 폴더
- FileInputStrea, FileOutputStream 사용
- 앱 데이터 폴더 경로를 사용한다.
1. 앱 데이터 폴더 경로 가져오기!
file_path = getExternalFilesDir(null).toString()
- null을 지정할 경우, 앱 데이터 폴더 경로가 반환된다.
- ‘ENVIRONMENT.____‘로 특정 폴더를 지정할 경우, 해당 폴더의 경로가 반환된다.
2. 앱 데이터 폴더에 데이터 저장!
val fos = FileOutputStream("$file_path/data2.dat")
val dos = DataOutputStream(fos)
dos.writeInt(20)
dos.writeBoolean(false)
dos.writeUTF("test2")
dos.flush()
dos.close()
3. 앱 데이터 폴더에서 데이터 읽어오기!
val fis = FileInputStream("$file_path/data2.dat")
val dis = DataInputStream(fis)
val data1 = dis.readInt()
val data3 = dis.readBoolean()
val data4 = dis.readUTF()
dis.close()
🙋♀️외부 저장소: 공용 파일
- 파일 관리 앱의 액티비티를 이용한다.
1. 파일을 만들어 사용하기 위해 파일 관리 앱 액티비티 실행!
val fileIntent = Intent(Intent.ACTION_CREATE_DOCUMENT)
fileIntent.addCategory(Intent.CATEGORY_OPENABLE)
fileIntent.type = "*/*"
startActivityForResult(fileIntent, 100)
- Intent로 파일 관리 앱 액티비티를 실행한다.
- ACTION_CREATE_DOCUMENT: 파일을 만들어 사용하기 위한 용도
- CATEGORY_OPENABLE: 파일을 열 수 있도록 지정
- 열어 볼 타입 지정
- ‘image/*’: 모든 이미지 파일
-
Intent 실행 결과로 사용자가 지정한 파일에 대해서 해당 코드 실행! (쓰기 실행)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if(requestCode == 100) { if (resultCode == RESULT_OK) { // 핵심! // w: 쓰기 모드로 사용 val des1 = contentResolver.openFileDescriptor(data?.data!!, "w") val fos = FileOutputStream(des1?.fileDescriptor) val dos = DataOutputStream(fos) dos.writeInt(300) dos.writeBoolean(true) dos.writeUTF("test3") dos.flush() dos.close() } } }
공용 파일을 읽기 위해 파일 관리 앱 액티비티 실행!
val fileIntent = Intent(Intent.ACTION_OPEN_DOCUMENT)
fileIntent.type = "*/*"
startActivityForResult(fileIntent, 200)
- ACTION_OPEN_DOCUMENT: 데이터를 읽어 오는 용도
- Intent 실행 결과로 사용자가 지정한 파일에 대해서 해당 코드 실행! (읽기 실행)
- 위 onActivityResult 코드에 이어서 작성!
}else if(requestCode == 200){
if(resultCode == RESULT_OK) {
# 핵심!
# r: 읽기 모드로 사용
val des2 = contentResolver.openFileDescriptor(data?.data!!, "r")
val fis = FileInputStream(des2?.fileDescriptor)
val dis = DataInputStream(fis)
val data1 = dis.readInt()
val data3 = dis.readBoolean()
val data4 = dis.readUTF()
dis.close()
}
}
📃참고
- 인프런 윤재성의 Kotlin 기반 안드로이드 앱 개발 Part3 수강
댓글남기기