백준이나 프로그래머에서 입출력 관련 문제를 풀 때, readLine()이나 println()을 사용하면 시간초과로 Fail나는 경우가 있는데요. 이 때, BufferedReader()이나 BufferedWriter()을 사용하면 해결됩니다.
BufferedReader, BufferedWriter와 readLine,println은 무슨 차이점을 가지길래 속도 차이가 나는지 한 번 알아보겠습니다.
1. BufferedReader(), BufferedWriter()와 readLine(), println()의 차이점
- readLine()은 기본적으로 한 줄의 텍스트를 읽어 반환합니다. 이 메서드는 한 번에 한 줄씩 읽으므로 파일의 크기나 줄 수에 따라 I/O 속도가 떨어질 수 있습니다. 특히 대용량 파일의 경우, readLine()은 상대적으로 느릴 수 있습니다.
- BufferedReader는 데이터를 버퍼링하여 한 번에 많은 양의 데이터를 읽어들이고 메모리에 저장한 다음 한 줄씩 읽어옵니다. 이로 인해 I/O 작업이 빠르게 처리되며, 대용량 파일에서도 효율적으로 작동합니다.
(2) println()와 BufferedWriter()
- println()는 텍스트 데이터를 출력할 때 사용되며, 텍스트 데이터를 직접 출력합니다. 출력 작업은 호출될 때마다 즉시 발생하며, 이는 출력 속도에 영향을 미칩니다. 여러 번 호출할 때마다 파일에 데이터를 쓰는 작업이 발생하므로 성능 저하의 원인이 될 수 있습니다.
- BufferedWriter는 데이터를 버퍼에 쓰고 나중에 한 번에 디스크에 쓰는 방식을 사용합니다. 이로 인해 데이터를 버퍼에 쓰는 작업은 빠르게 수행되며, 여러 작업을 버퍼에 쌓아두고 나중에 한꺼번에 디스크에 쓸 수 있어 성능이 향상됩니다. 특히 여러 작업이 동시에 발생하는 경우에 유용합니다.
따라서, BufferedReader 및 BufferedWriter를 사용하면 파일에서 데이터를 읽고 쓸 때 I/O 속도가 향상되며, 대용량 데이터와 빈번한 출력 작업에 대해 더 효율적입니다. readLine() 및 println() 메서드는 간단한 작업에는 적합하지만 대규모 데이터 처리나 높은 성능을 요구하는 상황에서는 성능 저하의 가능성이 있습니다.
2. BufferedReader()과 BufferedWriter()
- BufferedReader는 문자 데이터를 읽을 때 버퍼링된 I/O를 제공하는 클래스입니다. 버퍼링은 파일에서 데이터를 읽을 때 한 번에 많은 양의 데이터를 읽어들이고 메모리에 저장한 다음 데이터를 한 줄씩 읽어올 수 있게 해줍니다. 이렇게 하면 데이터 읽기 작업이 효율적으로 처리됩니다.
(2) BufferedWriter
import java.io.BufferedReader
import java.io.FileReader
fun main() {
val file = FileReader("sample.txt")
val bufferedReader = BufferedReader(file)
var line: String?
//파일에서 한줄씩 읽어와서 출력
while (bufferedReader.readLine().also { line = it } != null) {
println(line)
}
bufferedReader.close() //리소스 해제
}
(2) BufferedWriter
- BufferedWriter는 문자 데이터를 파일에 쓸 때 버퍼링된 I/O를 제공하는 클래스입니다. 버퍼링을 사용하면 데이터를 한 번에 많은 양으로 쓰고 디스크에 저장하므로 파일 쓰기 작업이 효율적으로 처리됩니다.
import java.io.BufferedWriter
import java.io.FileWriter
fun main() {
val file = FileWriter("output.txt")
val bufferedWriter = BufferedWriter(file)
val text = "This is a sample text to be written to the file."
bufferedWriter.write(text) // 텍스트를 파일에 쓰기
bufferedWriter.flush() //버퍼 비우고 출력
bufferedWriter.close() //리소스 해제
}
※ 버퍼링된 I/O : 데이터를 읽거나 쓸 때 발생하는 I/O 작업을 최적화하기 위한 메커니즘