안드로이드 파일처리

이영준·2023년 3월 17일
0

NodeStream

Processing Stream

노드스트림, 프로세스 스트림을 사용하는 자바의 방식과 같음

📌 파일 만들고 저장하기

private lateinit var file: File
file = File(filesDir, "data.txt")

저장할 파일은 위와 같이 선언한다.
filesDir은 context가 제공하는 것으로 data/data/패키지/files에 data.txt라는 이름으로 들어갈 것이다.

이 파일은 사용자가 접근 할 수 없다

private fun saveFile(){
        try {
            // use: try use resource
            BufferedWriter(FileWriter(file, true)).use {
                it.append("지금 시각은 ${Date()} 입니다.\n")
            }
            statusTV.text = "저장 완료"
        }catch(e:IOException){
            Log.e(TAG, "saveFile: ", e)
        }
    }

파일을 저장하는 코드이다.
use를 쓰면 writer사용이 끝나고 자동으로 close해준다.
업로드중..

📌 파일 읽어오기

private fun loadFile(){
        Log.d(TAG, "file: ${file.canonicalPath}")
        try {
            //useLines : BufferedReader로 한줄씩 읽어서 처리. 모두 읽으면 close한다.
            BufferedReader(FileReader(file)).useLines {
                //fold : 초기값을 설정하고 요소의 첫번째 부터 람다식 오른쪽의 누적값으로 적용하여 accu가 되고, 다음값으로..
                var data =it.fold(""){
                    accu, now ->
                    "$accu\n$now"
                }
                Log.d(TAG, "loadFile: $data")
                statusTV.text = data
            }

        }catch(e:IOException){
            Log.e(TAG, "loadFile: ", e)
        }
    }

fold는 데이터들을 순차적으로 누적하여 더해주는 역할을 한다.
https://velog.io/@blucky8649/%EC%BD%94%ED%8B%80%EB%A6%B0-reduce-fold-%ED%95%A8%EC%88%98

📌 assets 파일 읽기

다른 kt 파일 등은 바이트코드로 변환되어 저장되지만assets 폴더 내의 파일은 txt파일 자체를 그대로 처리하도록 해준다.

private fun loadAssets(){
        try{
            BufferedReader(InputStreamReader(assets.open("data.txt"))).useLines {
                var data =it.fold(""){
                        accu, now ->"$accu\n$now"
                }
                Log.d(TAG, "loadFile: $data")
                statusTV.text = data
            }
        }catch(e:IOException){
            Log.e(TAG, "onCreate: assets 파일 로딩 실패", e)
        }
    }

assets키워드는 assetManager가 관리하며 asset 폴더에 접근할 수 있게 해준다. 이를 통해
assets내의 data.txt 파일을 읽을 수 있다.

📌 외부 경로에 파일 저장하기

사용자가 직접 파일에 접근하여 읽을 수 있도록 외부저장소에 파일을 저장할 수도 있다.

       externalBtn.setOnClickListener {
            Log.d(TAG, "현재 미디어의 상태 ${Environment.getExternalStorageState()}")
            Log.d(TAG, "외장 메모리 경로: ${getExternalFilesDir(null)}") // null: 시스템 default 경로 리턴.
            if(Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED){
                val file = File(getExternalFilesDir(null), "data.txt")
                try{
                    //FileWriter(file, true) 이면 기존파일에 추가.
                    BufferedWriter(FileWriter(file)).use {
                        it.append("외부 저장소에 write 하기")
                    }
                    BufferedReader(FileReader(file)).useLines {
                        //fold : 초기값을 설정하고 요소의 첫번째 부터 람다식 오른쪽의 누적값으로 적용하여 accu가 되고, 다음값으로..
                        val lines = it.fold(""){
                                accu, now ->"$accu\n$now"
                        }
                        statusTV.text = lines
                    }
                }catch(e: IOException){
                    Log.e(TAG, "onCreate: 외장 메모리 사용 실패", e)
                }
            }else{
                Toast.makeText(this, "이 기기는 외장 메모리를 지원하지 않습니다.", Toast.LENGTH_SHORT).show()
            }
        }
    }

D/FileOutActivity싸피: 현재 미디어의 상태 mounted
D/FileOutActivity
싸피: 외장 메모리 경로: /storage/emulated/0/Android/data/com.ssafy.ui6/files

sybolic link 경로 : mnt > sdcard> Android> data> 패키지>files>data.txt
파일 위치 확인을 해보면
외장 메모리 경로 로그가 나오는 곳에도 있고 위의 경로에도 파일이 있는데, 이유는 symbolic link로 sd card 가 있는 것처럼 파일 경로가 표출되기 때문이다.

profile
컴퓨터와 교육 그사이 어딘가

0개의 댓글