BufferedReader / BufferedWriter
bufferedReader, bufferedWriter는 이름에서 확인할 수 있듯이 버퍼를 이용하여 읽고 쓰는 역할을 하는 메서드입니다.
버퍼란?
- 버퍼는 데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 메모리 영역.
자바의 Scanner와 BufferedReader의 차이점
- Scanner는 띄어쓰기(스페이스)와 줄바꿈(엔터, 개행문자)를 경계로 값을 인식
- BufferedReader는 줄바꿈(엔터, 개행문자)만 경계로 인식 + 데이터의 타입이 무조건 String으로 고정.
버퍼를 사용하지 않는 입력(Scanner)는 키보드의 입력이 키를 누르는 즉시 바로 프로그램에게 전달이 되지만,
버퍼를 사용하는 입력(BufferedReader)는 키보드의 입력이 있을 때마다 한 문자씩 버퍼로 전송한 후, 버퍼가 가득 차거나 줄 바꿈(\n)이 나타나면 버퍼에 쌓인 내용을 한 번에 프로그램에 전송해줍니다.
이렇게 버퍼를 사용하지 않는 입력은 키보드의 입력이 되는 즉시 프로그램에 보내지고, 버퍼를 사용하는 입력은 버퍼에 저장되었다가 한 번에 보내면 더 비효율인 것처럼 생각될 수 있다. 하지만 데이터의 입출력은 자원이 많이드는 작업이기 때문에 하나씩 바로바로 보내주는 것보다 모아서 한번에 보내주는 것이 더 효율적입니다.
예를들면, 무거운 상자들을 먼 거리로 옮겨야하는 상황일 때 버퍼는 사용하지 않는 입력은 상자를 하나씩 옮기는 것이고 버퍼를 사용하는 입력은 엘카(물건들을 적재한 후 한 번에 옮기게 해주는 도구)에 물건들을 쌓고 한 번에 옮기는 것입니다.
이러한 특징으로 빠른 입/출력이 가능한 BufferedReader, BufferedWriter는 자바 / 코틀린으로 입출력을 다뤄야하는 알고리즘 문제를 풀때 입출력 시간을 단축시키기위하여 사용하는 모습을 자주 볼 수 있습니다.
BufferedReader 사용하기
import java.io.BufferedReader
import java.io.File
import java.io.FileReader
fun main() {
// 예외 처리하기
try {
// 콘솔로 입력을 받을 때
// val br = BufferedReader(InputStreamReader(System.`in`))
// 파일 경로 설정
val path = System.getProperty("user.dir") + "/src/main/kotlin"
// 파일 객체 생성
val file = File(path, "test.txt")
// 파일에서 입력을 받을 때(파일 읽기)
val br = BufferedReader(FileReader(file))
// 파일의 끝까지 한 줄씩 반복해서 출력(String)
while (true) {
// 무조건 string으로 반환, 다른 데이터 타입은 형변환이 필요함.
val line = br.readLine() ?: break
println(line)
}
br.close()
} catch (e: Exception) {
println("$e 에러 발생")
}
}
이 코드는 현재 디렉터리 + /src/main/kotlin에 있는 test.txt라는 이름을 가진 파일을 읽어온 후 한 줄씩 출력해주는 코드입니다.
try catch 구문을 사용하여 예외처리를 해주었습니다.
콘솔로 직접 입력을 받을 때에는 맨 위에 주석처리된 val br = BufferedReader(InputStreamReader(System.`in`)) 와 같이 사용하면 됩니다.
// 파일의 끝까지 한 줄씩 반복해서 출력(String)
while (true){
// 무조건 string으로 반환, 다른 데이터 타입은 형변환이 필요함.
val line = br.readLine() ?: break
println(line)
}
br.readLine()을 통해 해당 파일의 내용을 한줄씩 반복해서 읽고, 출력하는 부분입니다. BufferedReader는 '\n' 즉, 줄바꿈을 기준으로 문자열을 나누기 때문에 만약 공백, 혹은 특정 문자를 기준으로 문자열을 더 나누고 싶다면 split함수 혹은 StringTokenizer를 사용하여 문자열을 더 나눠줄 수 있습니다.
BufferedReader 클래스의 또 다른 메인 함수들
- close() - void 반환
- 입력스트림을 종료하고 사용하던 자원들을 방출하는 메서드
- mark(int readAheadLimit) - void 반환
- 스트림의 현재 위치를 마킹하는 메서드
- markSupported() - boolean 반환
- 스트림이 mark 기능을 지원하는지 true/false 여부로 알려주는 메서드
- read() - int 반환
- 한 글자만 읽은 후 아스키 코드를 정수형으로 반환해주는 메서드
- ex) 1을 읽었다면 49라는 정수를 반환
- read(char[] cbuf, int offset, int length) - int 반환
- cbug의 offset 위치부터 length 길이만큼 문자를 스트림으로부터 읽어오는 메서드
- readLine() - String 반환
- 한 줄을 읽은 후 해당 문자열을 String으로 반환하는 메서드
- ready() - boolean 반환
- 입력스트림이 사용할 준비가 되어있는지 확인해주는 메서드
- reset() - void 반환
- 마킹이 있다면 그 위치부터 다시 시작, 그렇지 않으면 처음부터 다시 시작하는 메서드
- skip(long n) - long 반환
- n개의 문자를 건너뛰는 메서드
BufferedWriter 사용하기
import java.io.*
fun main() {
// 콘솔에서 BufferedReader로 입력 받기
val br = BufferedReader(InputStreamReader(System.`in`))
// 입력받은 데이터에서 한줄만 input에 String으로 저장
val input = br.readLine()
// BufferedWriter 객체 생성
val bw = BufferedWriter(OutputStreamWriter(System.out))
// input을 저장 쓰기
bw.write(input)
// 개행문자 쓰기
bw.newLine()
// 문자열이라는 문자열을 쓰기
bw.write("문자열")
// 버퍼에 남아있는 데이터들을 출력 후 비우기 - 콭솔에 출력
bw.flush()
// 스트림 종료
bw.close()
// 여기부터는 파일 쓰기
// 파일을 생성할 경로 지정
val path = System.getProperty("user.dir") + "/src/main/kotlin"
// 파일의 경로, 생성할 파일의 이름을 가지는 File 객체 생성
val file = File(path, "test.txt")
// FileWriter 객체 생성
val fileWriter = FileWriter(file)
// 생성할 파일, 경로의 정보가 담긴 FileWriter를 가지는 파일 생성용 BufferedWriter 객체 생성
val bwForFile = BufferedWriter(fileWriter)
// input을 쓰기
bwForFile.write(input)
// 개행문자 쓰기
bwForFile.newLine()
// 문자열이라는 문자열을 쓰기
bwForFile.write("문자열")
// 버퍼에 남은 값 출력 및 비우기
bwForFile.flush()
// 스트림 종료
bwForFile.close()
}
이 코드는 두 가지의 BufferedWriter의 기능이 담겨있습니다.
첫 번째는 콘솔에서 BufferedReader로 입력받아 BufferedWriter로 콘솔창에 출력하는 것이고
두 번째는 BufferedWriter로 파일쓰기를 하는 것입니다.
// input을 쓰기
bw.write(input)
// 개행문자 쓰기
bw.newLine()
// 문자열이라는 문자열을 쓰기
bw.write("문자열")
// 버퍼에 남아있는 데이터들을 출력 후 비우기 - 콭솔에 출력
bw.flush()
// 스트림 종료
bw.close()
write()는 인자로 들어온 문자열을 버퍼에 저장하는 메서드이고
newLine()은 개행 문자를 버퍼에 저장하는 메서드 입니다.
flush()는 버퍼에 남아있는 데이터들을 출력하고 비워줍니다.
// 여기부터는 파일 쓰기
// 파일을 생성할 경로 지정
val path = System.getProperty("user.dir") + "/src/main/kotlin"
// 파일의 경로, 생성할 파일의 이름을 가지는 File 객체 생성
val file = File(path, "test.txt")
// FileWriter 객체 생성
val fileWriter = FileWriter(file)
// 생성할 파일, 경로의 정보가 담긴 FileWriter를 가지는 파일 생성용 BufferedWriter 객체 생성
val bwForFile = BufferedWriter(fileWriter)
// input을 쓰기
bwForFile.write(input)
// 개행문자 쓰기
bwForFile.newLine()
// 문자열이라는 문자열을 쓰기
bwForFile.write("문자열")
// 버퍼에 남은 값 출력 및 비우기
bwForFile.flush()
// 스트림 종료
bwForFile.close()
쓰기를 진행할 파일명, 경로의 정보를 가지는 FileWriter 객체를 BufferedWriter에게 넘겨주어 해당 경로에 해당 파일명을 가지는 파일을 쓰도록 지정해줍니다.
BufferedWriter 클래스의 또 다른 메인 함수들
- flush()
- 스트림을 비워주는 메서드
- close()
- 스트림을 닫는 메서드. flush()를 먼저 해야함.
- newLine()
- 개행문자를 쓰는 메서드
- write(char[] cbuf, int offset, int length)
- 버퍼 offset 위치부터 length 크기만큼 쓰는 메서드
- write(int c)
- 한 글자를 쓰는 메서드
- write(String s, int offset, int length)
- 문자열에서 offset부터 일정 길이만큼 쓰는 메서드
참고
'코틀린[Kotlin]' 카테고리의 다른 글
입력 스트림과 출력 스트림(InputStream & OutputStream) / FileInputStream & FileOutputStream과 FileReader & FileWriter의 차이 (0) | 2022.08.06 |
---|---|
코틀린에서 디렉터리 생성, 문자 기반의 파일(텍스트 파일) 생성 및 읽기 - 파일 입출력(FileWriter / FileReader) (0) | 2022.08.06 |
코틀린에서 Thread 사용하기( + start()-스레드 시작, join()-스레드 대기상태로 만들기) (0) | 2022.07.31 |
코틀린으로 크롤링하기(Jsoup) (0) | 2022.07.20 |
코틀린(Kotlin)에서 큐(Queue) 사용하기 (1) | 2022.07.08 |
최근댓글