Android Kotlin : 폴더 생성, 탐색, 삭제
File 클래스 기본 사용법에 대해 알아보고, 앱 전용 디렉토리에서 폴더 생성, 탐색, 삭제 하는 기능에 대해 정리
하였습니다. 이 포스트에는 저장소의 개념과 AlertDialog 사용법을 포함하고 있어 필요하신 분은 아래의 링크를 참조해주세요.
기본 사용법
저장소 경로 불러오기
- 앱 전용 디렉토리(내부저장소) : getFilesDir()
- 앱 전용 디렉토리(외부저장소) : getExternelFilesDir()
File 클래스 기본 사용법
File 클래스에서 주로 사용되는 사용법은 아래와 같이 코드로 정리하였습니다.
// File 클래스 인스턴스 만들기
val file = File("PATH") // 전체 경로를 입력
// 파일 또는 폴더 존재 유무 확인
if(file.exists()) {
println("파일이 존재합니다")
}
// file 이 파일인지 폴더 인지 확인
if(file.isFile) {
println("파일입니다.")
}
if(file.isDirectory) {
println("폴더입니다.")
}
// 폴더 또는 파일 생성
if(!file.isFile) {
file.createNewFile()
}
if(!file.exists()) {
file.mkdirs()
}
// 파일 또는 디렉토리 삭제
file.delete()
// 파일 이름 반환
val fileName = file.name
// 파일 절대 경로 반환
val filePath = file.absolutePath
※ File 클래스는 파일을 읽고 쓰는 기능은 포함되어 있지 않습니다. 파일을 읽고 쓰기 위해서는 Stream이라는 클래스를 사용해야 합니다.
프로젝트 생성 및 환경설정
프로젝트 생성
아래 그림과 같이 프로젝트를 생성합니다.
- 프로젝트명 : ManagingFolder
- 사용 언어 : Kotlin
ViewBinding 설정
build.gradle(Module: ManagingFolder) 파일에 아래의 ViewBinding 설정 코드를 추가합니다.
android {
...
viewBinding {
enabled = true
}
}
코드 추가가 완료되면 아래와 같이 Sync Now 클릭해서 Gradle 변경 사항을 적용합니다.
ViewBinding 은 Layout 에 있는 View의 Id를 코틀린 코드에서 직접 사용 할 수 있게 해주는 도구입니다. View Binding과 관련된 설명은 아래의 링크를 참조해주세요.
레이아웃 작성
activity_main.xml 코드 작성
activity_main.xml 레이아웃 파일에 아래와 같이 4개의 버튼과 1개의 텍스트뷰 등록 코드를 작성합니다. 버튼과 텍스트 뷰의 기능은 아래와 같습니다.
- Show App Directory Path 버튼: 앱 디렉토리 절대 경로 보여주기
- Make Directory 버튼 : 앱 디렉토리에 특정 이름 폴더 추가
- Load FileLists 버튼 : 앱 디렉토리의 파일 리스트 TextView에 출력
- Delete Directory 버튼 : 앱 디렉토리의 특정 이름 폴더 삭제
- TextView : Load FileLists 버튼을 누르면 앱 디렉토리의 파일 리스트 출력
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btnGetDir"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="Show App Directory Path"
android:textAllCaps="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btnMkdir"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="Make Directory"
android:textAllCaps="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnGetDir" />
<Button
android:id="@+id/btnFileList"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="Load FileLists"
android:textAllCaps="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnMkdir" />
<Button
android:id="@+id/btnDeleteDir"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="Delete Directory"
android:textAllCaps="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnFileList" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="FileList"
android:textSize="20sp"
android:layout_margin="8dp"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
코틀린 코드 작성
앱 전용 디렉토리 경로 불러오기
앱 전용 디렉토리는 앱 마다 생성되는 별도의 디렉토리 입니다. 앱은 기본적으로 내부저장소의 /data/data/{package_name} 경로에 저장됩니다. /data/data/{package_name} 경로는 내부적으로 /data/user/0/{package_name} 경로와 연결되어 있습니다. 앱 전용 디렉토리를 불러오기 위해 아래와 같이 코드를 작성합니다.
package com.blacklog.managingfolder
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import com.blacklog.managingfolder.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
binding.btnGetDir.setOnClickListener {
toast(filesDir.toString())
}
}
fun toast(message:String){
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
}
ViewBinding 설정 코드가 있어 불 필요하게 코드가 길지만, filesDir만 사용하여 앱 전용 디렉토리를 간단하게 불러 올 수 있습니다. filesDir은 getFilesDir() 의 반환값입니다.
디렉토리 생성
UI의 Make Directory 버튼을 누르면 EditText가 포함된 AlertDialog에서 폴더명을 입력받아 새 폴더를 추가하는 방식으로 코드를 작성하였습니다. EditText가 포함된 AlertDialog를 만들기 위해 아래와 같이 레이아웃 파일을 추가하고 코드를 작성합니다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:layout_marginEnd="22dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt 의 onCreate() 함수내에 아래의 버튼 리스너 코드를 추가합니다.
package com.blacklog.managingfolder
import android.content.DialogInterface
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import com.blacklog.managingfolder.databinding.ActivityMainBinding
import com.blacklog.managingfolder.databinding.AlertdialogEdittextBinding
import java.io.File
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
binding.btnGetDir.setOnClickListener {
toast(filesDir.toString())
}
binding.btnMkdir.setOnClickListener {
val alertDialogEditText = AlertdialogEdittextBinding.inflate(layoutInflater)
val builder = AlertDialog.Builder(this)
.setTitle("Input Directory Name")
.setView(alertDialogEditText.root)
.setPositiveButton("OK"){ dialogInterface: DialogInterface, i: Int ->
makeDirectory(alertDialogEditText.editText.text.toString())
}
.show()
}
}
fun makeDirectory(folderName:String){
val path = File("$filesDir/$folderName")
if(!path.exists()){
path.mkdirs()
}else{
toast("$folderName is exists")
}
}
fun toast(message:String){
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
}
위 코드를 빌드후 Make Directory 버튼을 클릭하면 아래 그림과 같이 AlertDialog를 통해 입력 받은 폴더 이름이 앱 전용 디렉토리의 files 폴더에 추가된 것을 확인 할 수 있습니다.
파일 리스트 보기
Load FileLists 버튼을 누르면 앱 전용 디렉토리의 files 폴더에 있는 파일 및 폴더 리스트를 TextView에 출력합니다. 기능을 추가하기 위해 MainActivity.kt 파일의 onCreate() 함수내에 아래의 버튼 리스너 코드를 추가합니다.
binding.btnFileList.setOnClickListener {
binding.textView.text = null
val path = File(filesDir.toString())
val files = path.listFiles()
var strFileList: String? = "App Directory File Lists\n"
for(file in files){
strFileList += "->" + file.name + "\n"
}
binding.textView.text = strFileList
}
위 코드를 추가하고 실행 후 Load FileLists 버튼을 클릭하면 파일리스트가 하단의 TextView에 출력됩니다.
디렉토리 삭제하기
디렉토리 삭제 기능은 지난 포스트에서 소개한 AlertDialog의 체크박스 기능으로 구현하였습니다. 파일 및 폴더 리스트를 체크 박스 리스트로 등록 후 선택된 항목은 삭제하는 코드입니다. 이 기능을 추가하기 위해 MainActivity.kt에 아래의 버튼 리스너 코드를 추가합니다.
binding.btnDeleteDir.setOnClickListener {
val files = File(filesDir.toString()).listFiles()
val selectedItemIndex = ArrayList<Int>()
var filesName = Array(files.size) { item -> "" }
for(i in files.indices){
filesName[i] = files[i].name
}
val builder = AlertDialog.Builder(this)
.setTitle("삭제할 디렉토리 선택")
.setMultiChoiceItems(filesName, null){ dialogInterface: DialogInterface, i: Int, b: Boolean ->
if(b){
selectedItemIndex.add(i)
}else if(selectedItemIndex.contains(i)){
selectedItemIndex.remove(i)
}
}
.setPositiveButton("삭제"){ dialogInterface: DialogInterface, i: Int ->
for(i in selectedItemIndex.indices){
val file = File("$filesDir/${filesName[selectedItemIndex[i]]}")
file.delete()
}
}
val dialog = builder.create()
dialog.show()
}
AlertDialog 빌더를 사용하여 체크 박스 목록을 만들어 이벤트 처리하는 방법은 하단의 관련포스트를 참고해주세요. 위 코드를 작성 후 실행하면 Delete Directory 버튼 클릭시 아래와 같이 동작합니다.
끝까지 읽어 주셔서 감사합니다.^^
'Programming > Android App(Kotlin)' 카테고리의 다른 글
안드로이드 코틀린 : Fragment 추가, 변경, 삭제 사용법 및 유의점 (1) | 2021.03.25 |
---|---|
안드로이드 코틀린 : Intent 명시적 호출 방법 정리 (0) | 2021.03.25 |
안드로이드 코틀린 : AlertDialog 기본, 목록, 라디오 버튼, 체크 박스, EditText 입력 창 (0) | 2021.03.23 |
안드로이드 코틀린 : 토스트(Toast) 팝업 메세지 사용법 및 전역 함수로 사용법 (2) | 2021.03.19 |
안드로이드 저장소 정리 : 앱 전용 디렉토리? 내부 저장소? 외부 저장소? 공용저장소 (0) | 2021.03.17 |