안드로이드 개발자의 창고
[43일차 Android] 파일 입출력 본문
출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 PPT
📖 파일 입출력
- 안드로이드는 애플리케이션이 데이터를 저장할 수 있는 저장소를 두가지로 제공하고 있다.
- 내부 저장소
- 애플리케이션을 통해서만 접근이 가능하다.
- openFileInput, openFileOutput
- 외부 저장소
- 단말기 내부의 공유 영역으로 모든 애플리케이션이 접근 가능하다.
- 단말기를 컴퓨터에 연결하면 탐색기를 통해 접근할 수 있는 영역을 의미한다.
- FileInputStream, FileOutputStream
- 내부 저장소
- Scoped Storage 정책
- 외부 저장소에 저장된 파일은 모든 애플리케이션이 접근할 수 있어 보안에 문제가 발생함에 따라 보안 강화를 위해 외부 저장소 접근을 제한한 정책
예제 코드
내부 저장소
- 파일을 저장한 애플리케이션만 사용이 가능하다.
button.setOnClickListener {
// MODE_PRIVATE : 덮어 씌우기
// MODE_APPEND : 이어서 쓰기
val fos = openFileOutput("data1.dat", MODE_PRIVATE)
val dos = DataOutputStream(fos)
// 데이터 쓰기
dos.writeInt(100)
dos.writeDouble(11.11)
dos.writeBoolean(true)
dos.writeUTF("문자열1")
dos.flush()
dos.close()
textView.text = "내부 저장소 쓰기 완료"
}
button2.setOnClickListener {
// 파일 읽기
val fis = openFileInput("data1.dat")
val dis = DataInputStream(fis)
// 데이터 읽기
val data1 = dis.readInt()
val data2 = dis.readDouble()
val data3 = dis.readBoolean()
val data4 = dis.readUTF()
dis.close()
fis.close()
// 읽어온 데이터를 textView에 반영
textView.text = "data1 : ${data1}\n"
textView.append("data2 : ${data2}\n")
textView.append("data3 : ${data3}\n")
textView.append("data4 : $data4")
}
결과
Device File Explorer - data - data - 해당 앱의 패키지 이름 - files 폴더 확인
실행화면
외부 저장소
button3.setOnClickListener {
// 외부 저정소의 경로를 가져온다.
// emulated/Android/data/패키지명/files
val filePath = getExternalFilesDir(null).toString()
// getExternalFilesDir 메서드의 매개변수에는 문자열을 넣어줄 수 있으며 files의 하위 폴더 이름을 넣어서 사용할 수 있다.
// null을 넣으면 files까지의 경로가 된다.
val fos = FileOutputStream("${filePath}/data2.dat")
val dos = DataOutputStream(fos)
// 데이터 쓰기
dos.writeInt(200)
dos.writeDouble(22.22)
dos.writeBoolean(false)
dos.writeUTF("문자열2")
dos.flush()
dos.close()
fos.close()
textView.text = "외부 저장소 앱 데이터 폴더에 저장"
}
button4.setOnClickListener {
// 파일 읽어오기
val filePath = getExternalFilesDir(null).toString()
val fis = FileInputStream("${filePath}/data2.dat")
val dis = DataInputStream(fis)
// 데이터 읽기
val data1 = dis.readInt()
val data2 = dis.readDouble()
val data3 = dis.readBoolean()
val data4 = dis.readUTF()
dis.close()
fis.close()
// 읽어온 데이터를 textView에 반영
textView.text = "data1 : ${data1}\n"
textView.append("data2 : ${data2}\n")
textView.append("data3 : ${data3}\n")
textView.append("data4 : $data4")
}
결과
에뮬레이터의 파일 앱 - emulated - Android - data - 패키지명 - files에서 확인
실행 화면
File 앱을 통한 접근
// 쓰기용 런처
val contracts1 = ActivityResultContracts.StartActivityForResult()
writeActivityLauncher = registerForActivityResult(contracts1){
// 사용자가 저장할 파일을 선택하고 돌아오면 ResultCode는 RESULT_OK가 들어온다.
if(it.resultCode == RESULT_OK){
// 사용자가 선택한 파일의 정보를 가지고 있는 Intent로 파일 정보를 가져온다.
if(it.data != null){
// 저장할 파일에 접근할 수 있는 객체로 부터 파일 정보를 가져온다.
// w : 쓰기, a : 이어쓰기, r : 읽기
val des1 = contentResolver?.openFileDescriptor(it.data?.data!!, "w")
// 스트림을 생성한다.
val fos = FileOutputStream(des1?.fileDescriptor)
val dos = DataOutputStream(fos)
dos.writeInt(300)
dos.writeDouble(33.33)
dos.writeBoolean(true)
dos.writeUTF("문자열3")
dos.flush()
dos.close()
activityMainBinding.textView.text = "Downloads 폴더에 저장"
}
}
}
// 읽기용 런처
val contracts2 = ActivityResultContracts.StartActivityForResult()
readActivityLauncher = registerForActivityResult(contracts2){
// RESULT_OK 일 때만 동작하도록 설정
if(it.resultCode == RESULT_OK){
// 가져온 데이터가 있을 경우에만 동작
if (it.data != null){
// 선택한 파일의 경로 정보를 가져온다.
val dest1 = contentResolver.openFileDescriptor(it.data?.data!!, "r")
val fis = FileInputStream(dest1?.fileDescriptor)
val dis = DataInputStream(fis)
val data1 = dis.readInt()
val data2 = dis.readDouble()
val data3 = dis.readBoolean()
val data4 = dis.readUTF()
dis.close()
activityMainBinding.textView.text = "data1 : ${data1}\n"
activityMainBinding.textView.append("data2 : ${data2}\n")
activityMainBinding.textView.append("data3 : ${data3}\n")
activityMainBinding.textView.append("data4 : $data4")
}
}
}
button5.setOnClickListener {
// 파일 관리 앱의 액티비티를 실행한다.
val fileIntent = Intent(Intent.ACTION_CREATE_DOCUMENT)
fileIntent.addCategory(Intent.CATEGORY_OPENABLE)
// MimeType을 설정한다.
// MimeType이란? 파일에 저장되어 있는 데이터의 양식이 무엇인지를 타나내는 문자열
// https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/MIME_types
fileIntent.type = "*/*"
writeActivityLauncher.launch(fileIntent)
}
button6.setOnClickListener {
// 파일 관리 앱의 액티비티를 실행한다.
val fileIntent = Intent(Intent.ACTION_OPEN_DOCUMENT)
fileIntent.type = "*/*"
readActivityLauncher.launch(fileIntent)
}
결과
에뮬레이터 File 앱 - Download에서 확인
'Computer > Android' 카테고리의 다른 글
[44일차 Android] assets (0) | 2023.07.10 |
---|---|
[44일차 Android] Raw (0) | 2023.07.10 |
[43일차 Android] Application Class (0) | 2023.07.06 |
[42일차 Android] Code를 이용한 View 생성 (0) | 2023.07.06 |
[42일차 Android] XML을 이용한 View 객체 생성 (0) | 2023.07.06 |