[Java] Scanner VS BufferedReader
알고리즘 문제를 푸는 중 입력 처리에 대해 어떤 문제에 대해서는
Scanner를 사용하고 어떤 문제에서는BufferedReader를 사용하여 두 클래스에 차이점을 명확히 이해하기 위해 Scanner와 BufferedReader의 특징과 차이점을 정리하였습니다.
Scanner
Scanner 란?
Scanner는 Java에서 콘솔이나 파일과 같은 입력 소스로부터 데이터를 읽어오는데 사용되는 클래스입니다.Scanner는 입력을 다양한 데이터 타입으로 변환하는 기능을 제공하며, 공백이나 구분자를 기준으로 데이터를 쉽게 분리하여 처리할 수 있습니다.
Scnnaer 특징
- 다양한 데이터 타입 처리:
Scanner는 입력을 정수, 실수, 문자열 등 다양한 타입으로 변환할 수 있습니다.- 예:
nextInt(),nextDouble(),nextLine()
- 예:
- 기본 구분자 사용: 기본적으로 공백을 구분자로 사용하여 입력을 구분하지만,
useDelimiter()메서드를 사용하여 커스텀 구분를 설정할 수 있습니다. - 편리한 콘솔 입력: 콘솔에서 입력을 받아 처리할 때 코드가 직관적이고 간결합니다.
- 상대적으로 느린 성능: 입력을 파싱하고 분석하는 기능 때문에, 성능이 상대적으로 느리며, 대용량 데이터를 처리할 때 비효율적일 수 있습니다.
- 자동 형변환: 사용자가 명시한 타입으로 자동 형 변환이 이루어집니다. 예를 들어
nextInt()는 자동으로 정수형으로 입력을 변환합니다. - Thread-unsafe: 멀티스레드 환경에서 안전하지 않습니다.
BufferedReader
BufferedReader 란?
BufferedReader는 문자 입력을 버퍼링하여 효율적으로 읽을 수 있는 클래스입니다. 주로 텍스트 파일이나 네트워크로부터 데이터를 빠르게 읽어오는 데 사용되며, 큰 데이터를 처리할 때 적합합니다.
BufferedReader의 특징
- 버퍼링을 통한 성능 향상:
BufferedReader는 입력을 버퍼링하여 성능을 높이며, 특히 큰 데이터를 읽을 때 유리합니다. - 한 줄 단위로 입력 처리:
BufferedReader는readLine메서드를 사용하여 한번에 한 줄씩 입력을 처리합니다. - 단순한 입력 처리: 추가적인 파싱 기능은 제공하지 않으며, 입력된 데이터를 그대로 처리합니다.
- IO 예외 처리 필요:
BufferedReader는 입력 중에IOException이 발생할 수 있기 때문에, 예외 처리가 필수적입니다. - 대용량 데이터 처리에 적합: 파일에서 많은 데이터를 읽을 때 적합하며, 대규모 텍스트 파일 처리에 자주 사용됩니다.
- Thread-safe: 멀티스레드 환경에서 안전합니다.
버퍼링이란?
데이터를 임시 저장 공간(버퍼, buffer)에 저장하여 입출력 작업을 효율적으로 처리하는 기술로, 특히 입출력(I/O) 작업에서 성능을 향상시키는 데 중요한 역할을 합니다. 버퍼링을 사용하면 입출력 장치의 속도 차이를 보완할 수 있습니다.
Scanner vs BufferedReader
| 항목 | Scanner | BufferedReader |
|---|---|---|
| 입력 처리 방식 | 구분자 기반의 다양한 데이터 타입 변환 | 문자열로 한 줄씩 읽음 |
| 성능 | 상대적으로 느림 | 버퍼링을 통해 빠름 |
| 데이터 타입 | 정수, 실수, 문자열 등 여러 타입 지원 | 문자열만 처리 |
| 예외 처리 | 별도의 예외 처리 필요 없음 | IOException을 처리해야 함 |
| 사용 목적 | 콘솔 입력 및 간단한 입력 분석 | 파일, 네트워크 등에서 대용량 데이터 처리 |
| 동기화 | 동기화되지 않음 | 동기화되지 않음 |
| 구분자 설정 | 기본적으로 공백을 구분자로 사용 | 구분자 사용 불가 |
| 버퍼 메모리 용량 | 1KB | 8KB(많은 입력이 있을 경우 더 효율이지만 큰 메모리를 잡아먹는다) |
코드 예제
- Scanner
1
2
3
4
5
6
7
8
9
10
11
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // int 타입으로 데이터를 받아옴
String sNum = sc.next(); // String 타입으로 데이터를 받아옴.
...
- BufferedReader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Main {
public static void main(String[] args) throws IOException {
// BufferedReader 선언
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
// bufferedReader.readLine() 으로 한줄로 받은 문자열을 StringTokenizer를 통해 지정한 구분자로 쪼개준다.
StringTokenizer stringTokenizer = new StringTokenizer(bufferedReader.readLine());
// String으로 받아오기 때문에 필요하다면 아래처럼 직접 데이터 타입 변환이 필요하다.
int suNo = Integer.parseInt(stringTokenizer.nextToken());
int quizNo = Integer.parseInt(stringTokenizer.nextToken());
...
StringTokenizer 란?
문자열을 지정한 구분자로 문자열을 쪼개주는 클래스이다.
그렇게 쪼개진 문자열을 우리는 토큰(Token)이라고 부르며, java.util.StringToenizer 라이브러리를 import해야 사용할 수 있다.
마치며
Scanner 는 간단한 입력, 특히 콘솔 입력에서 다재다능한 클래스입니다. 다양한 데이터 타입을 처리 해야 하거나 구분자로 데이터를 나눌 때 적합합니다.
반면 BufferedReader는 대량의 데이터를 빠르게 읽어야 하는 경우, 특히 파일에서 데이터를 읽어올 때 성능이 우수하며, 문자열 단위로 정확히 데이터를 처리해야 할 때 적합한 클래스입니다.
따라서, 입력 데이터의 크기와 처리해야 할 데이터의 복잡성에 따라 두 클래스 중 적절한 것을 선택하는 것이 좋습니다.
참고
- https://velog.io/@langoustine/Scanner-VS-BufferedReader
