최근 알고리즘 연습문제들을 풀기 시작했는데 입출력 제한시간이 정해져있기도 하고 개인적으로도 입출력 시간을 단축하고 싶다는 생각이 들어 찾아보던 중 원래도 알고 있었고 실제로 사용도 해봤지만 자세히는 몰라 잘 사용하지 않던 BufferedReader와 BufferedWriter가 입출력 시간 단축에 도움이 된다는 글을 보고 사용하기 전에 한 번 제대로 공부해 봐야겠다는 생각이 들었다.
BufferdReader / BufferedWriter
BufferedReader와 BufferdWriter는 버퍼를 사용하여 데이터를 입출력하는 함수다.
설명만 들었을 때는 간단한데 버퍼가 무엇인지 잘 모르는 상태에서는 뜬 구름 잡는 소리처럼 들려 버퍼가 무엇인지에 대해 먼저 알아보기로 했다
Buffer란?
두개의 장치 사이에서 데이터 전송할 때 데이터의 전송 속도나 처리 속도의 차이를 완화하는 목적으로 사용하는 기억장치
즉 임시 저장 공간이라는 소리인데 이는 버퍼를 사용하지 않는 입력과 버퍼를 사용하는 입력의 동작을 뜯어보면 더 잘 이해할 수 있다
키보드를 통해 Read라는 단어를 입력한다고 해보자
버퍼를 사용하지 않는 입력의 경우
R입력->전달->e입력->전달->a입력->전달->d입력->전달
이런 방식으로 전달이 이루어지고 결과적으로 Read라는 단어를 입력하게 된다
한번의 전송에서 처리할 수 있는 양에 비해 현저히 적은 양의 데이터를 각각의 문자마다 전송하게 되는 것이다.
하지만 버퍼를 사용하여 입력하게 될 경우
R입력->버퍼에 저장->e입력->버퍼에 저장->a입력->버퍼에 저장->d입력->버퍼에 저장->전달
각각의 문자가 입력 될 때마다 버퍼에 임시로 저장되고 버퍼가 가득차거나 엔터 등으로 개행하게 될 시 버퍼에 쌓아뒀던 데이터를 한 번에 전송하게 되고 한 번의 전송으로 같은 양의 데이터를 처리할 수 있어 여러 번의 전송을 하는 것에 비해 효율적이고 빠른 데이터 입출력이 가능하게 된다
.
BufferedReader / Scanner
그럼 이제 본격적으로 BufferedReader에 대해 알아볼텐데 그 전에 처음 입출력에 대해 배울 때 Scanner라는 걸 먼저 배웠고 Scanner를 가지고 이제껏 잘 입력처리를 해 왔는데 BufferedReader와 어떤 차이가 있는 지 궁금해졌다.
Scanner의 특징
- 공백 및 개행을 경계값으로 인식한다.
- 데이터를 원하는 타입으로 파싱해 읽어올 수 있다.
- 버퍼의 사이즈가 1024byte(1KB) 이다.
- UnChecked(Runtime) Exception으로 별도로 예외 처리를 명시할 필요가 없다.
- Thread unsafe 성질을 지니기에 멀티스레드 환경에서 문제가 발생할 수 있다.
- 데이터를 입력받을 경우 즉시 사용자에게 전송된다.
Scanner는 크게 이런 특징들을 가지고 있는데 이 중 데이터를 Scanner가 가진 여러 함수들을 통해 파싱을 하고 데이터를 입력받는 즉시 사용자에게 전송하는 특성 때문에 속도면에서 떨어질 수 밖에 없다. 특히 단순입력의 양이 많아질수록 이러한 단점이 더욱 부각된다.
BufferedReader의 특징
- 개행만을 경계값으로 인식한다.
- 데이터를 파싱하지 않고 String으로만 읽고 가져온다.
- 버퍼의 사이즈가 8192byte(8KB)이다.
- Checked Exception으로 반드시 예외 처리를 명시해야한다.(I/O Exception을 throw하거나 try/catch 해야한다.)
- Thread safe 성질을 지니기에 멀티스레드 환경에서도 안전하다.
- 버퍼가 가득차거나 개행문자가 나타나면 버퍼의 내용을 한번에 프로그램으로 전달한다.
이에 반해 BufferedReader는 이러한 특징을 가지는데 파싱을 하지않고 문자가 입력될 때마다 전송되는 것이 아닌 버퍼에 쌓아두고 한 번에 전송하는 방식으로 인해 Scanner에 비해 더 빠르게 입력받을 수 있게 된다.
다만 이것은 입력시간에 이점이 있다는 것이지 모든 상황에서 Scanner보다 BufferedReader가 유리하다는 것은 아니다.
BufferedReader는 String 형식으로만 읽고 저장하기에 형변환을 위한 추가적인 코드 작성이 불가피한 반면에 Scanner는 원하는 타입으로 읽고 파싱할 수 있다. 그리고 BufferedReader의 경우 일단 큰 메모리를 잡아먹게 되고 예외처리 또한 따로 해주어야 하므로 이러한 특성들을 잘 고려하여 활용할 필요가 있다.
'Develop > Java & Spring' 카테고리의 다른 글
[Spring Boot] 게시판 프로젝트 외전 #1 JUnit과 Mockito를 이용한 테스트 - 이론 (0) | 2025.03.25 |
---|---|
[Spring Boot] 게시판 프로젝트 #4 Service, Controller 구현 (0) | 2025.03.25 |
[Spring Boot] 게시판 프로젝트 #3 DTO, Repository 구현 (0) | 2025.03.25 |
[Spring Boot] 게시판 프로젝트 #2 Domain(Entity), Util 구현 (0) | 2025.03.25 |
[Spring Boot] 게시판 프로젝트 #1 세팅 (0) | 2025.03.25 |