Study(종료)/Kotlin 22.09.13 ~ 12.18

7-2 컬렉션과 I/O 자세히 알아보기 : 파일과 I/O 스트림

Ski_ 2022. 10. 30. 20:47

7장

7-1. 컬렉션과 I/O 자세히 알아보기 : 컬렉션 타입 (1) (7-1.1~ 7-1.4)

7-1. 컬렉션과 I/O 자세히 알아보기 : 컬렉션 타입 (2) ( 7-1.5~ 7-1.7 )

7-1. 컬렉션과 I/O 자세히 알아보기 : 컬렉션 타입 (3) ( 7-1.8~ 7-1.11 )

7-2. 컬렉션과 I/O 자세히 알아보기 : 파일과 I/O 스트림


7-2. 파일과 I/O 스트림

입/출력 연산을 처리하는 표준 라이브러리 기능에 대해 작성해보겠다.

이 기능들은 자바에 있는 파일, I/O 스트림, URL 관련 API를 기반으로 만들어져JDK에 이미 있는 I/O 관련 클래스를 더 쉽게 사용할 수 있도록 해주는 확장 함수와 확장 프로퍼티를 제공한다.

 

1) 스트림 유틸리티

다음 함수들을 사용하면 스트림의 전체 콘텐츠를 읽어올 수 있다.

fun InputStream.readBytes(): ByteArray
fun Reader.readText(): String
fun Reader.readLines(): Line<String>

readText() / readLines()과 readLine()의 차이를 보자면

readLine()은 스트림에서 한 줄을 가져오지만, readText() / readLines()는 스트림 끝까지 콘텐츠를 읽어서

전체를 한 문자열이나 각 줄을 나타내는 문자열의 리스트로 반환한다.

FileWriter("data.txt").use{it.write("One\nTwo\nThree")} // write data.txt

FileReader("data.txt").buffered().use { println(it.readLine()) } // One
FileReader("data.txt").use { println(it.readText().replace('\n', ' ')) } // One Two Three
println(FileReader("data.txt").readLines()) // [One, Two, Three]

readText()를 이용해 파일 내용을 가져오는 경우 스트림을 닫아주어야 하고,

readLines()는 값을 반환하면서 스트림을 닫아준다.


2) 스트림 생성

bufferedReaders() / bufferedWriter() 확장 함수를 사용하면

지정한 File 객체에 대해 BufferedReader / BufferedWriter 인스턴스를 만들 수 있다.

비슷한 함수로 reader() / writer() 확장 함수도 있는데, 이는 각각 버퍼가 없는 FileReader / FileWriter 객체를 만든다.

printWriter() 함수는 형식화된 출력에 적합한 PrintWriter 인스턴스를 만든다.

val file = File("data.txt")
file.bufferedWriter().use { it.write("Hello Kotlin!") } // write
file.bufferedReader().use { println(it.readLine()) } // Hello Kotlin!
file.writer(charset = Charsets.UTF_8).use { it.write("안녕!") } // write
file.reader(charset = Charsets.ISO_8859_1).use { println(it.readLines()) } // [안녕!]
// 형식이 맞지 않아 문자가 깨짐
file.reader(charset = Charsets.UTF_8).use { println(it.readLines()) } // [안녕!]
file.printWriter(charset = Charsets.UTF_8)

3) URL 유틸리티

코틀린 표준 라이브러리는 URL 객체의 주소로부터 네트워크 연결을 통해 데이터를 읽어오는 함수를 제공한다.

fun URL.readText(charset: Charset = Charsets.UTF_8): String
fun URL.readBytes(): ByteArray

readText() 함수는 URL 인스턴스에 해당하는 입력 스트림의 콘텐츠를 전부 읽어오고,

readBytes() 함수는 입력 이진 스트림의 콘텐츠를 바이트 배열로 읽어온다.

두 함수 모두 전체 스트림 콘텐츠를 읽어오는 작업이 완료될 때 까지 스레드를 Block 시키므로

큰 파일을 다운로드 할 때 이 함수들을 사용해선 안된다.


4) 파일 콘텐츠 접근하기

코틀린 표준 라이브러리는 명시적으로 I/O 스트림을 쓰지 않고 파일 콘텐츠를 읽을 수 있는 함수를 제공한다.이런 함수는 전체 파일을 읽고 쓰고나, 데이터를 기존 파일 뒤에 추가하거나, 한 줄씩 파일을 처리해야 할 때 유용하다.

  • readText() : 파일 콘텐츠 전부를 한 문자열로 읽어온다.
  • readLines() : 파일 콘텐츠 전부를 줄 구분 문자를 사용해 줄 단위로 나눠 읽어 그 리스트를 반환한다.
  • writeText() : 파일 콘텐츠를 주어진 문자열로 설정한다. 필요할 경우 파일을 덮어쓴다.
  • appendText() : 주어진 문자열을 파일의 콘텐츠 뒤에 추가한다.

5) 파일 시스템 유틸리티

마지막으로 파일 복사, 삭제, 디렉토리 계층 구조 순회 등을 쉽게 할 수 있는 표준 라이브러리 함수가 있다.

  • deleteRecursively() 
    • 파일이나 디렉토리를 자신에게 포함된 하위 계층(자손)까지 삭제
    • 성공시 true, 실패시 false 반환
  • copyTo()
    • 자신의 수신 객체를 다른 파일에 복사하고 복사본을 가리키는 파일 객체를 반환
    • 이미 파일이 존재하는 경우 Exception throw, 강제로 복사하도록 파라미터 지정 가능
  • copyRecursively()
    • copyTo는 대상 경로에 맞춰 빈 디렉토리만 만들어줌
    • 내용물을 모두 복사하기 위해 사용하는 함수가 copyRecursively()
  • walk()
    • 깊이 우선 디렉토리 구조 순회 구현
    • TOP_DOWN : 자식보다 부모를 먼저 방문(기본값)
    • BOTTOM_UP : 자식을 부모보다 먼저 방문
  • onEnter() / onLeave()
    • 파일 순회시 디렉토리에 들어가거나 나올 때 호출할 동작 지정
  • createTmpFile() / createTmpDir()
    • 임시 파일이나 디렉토리 생성

꽤 긴 내용인데 스터디 시간에 맞춰서 겨우 작성했다.

다음단원은 8장 클래스 계층 이해하기이며, 상속, 추상 클래스 + 인터페이스에 대해 배운다.

이번단원은 꽤 긴 편이었고 정리하는데 오랜 시간이 걸렸다..

다음 단원 역시 소제목들을 봐보니 꽤 중요한 내용으로 예상된다.

이제 반정도 작성했는데 다음 단원도 열심히 작성해야겠다.

반응형