Scanner와 BufferedReader
한참 학원에서는 자바 진도를 나가고 있고 입력을 받기 위해 강사님께서 BufferedReader를 소개하며 클래스를 사용하라고 소개시켜주셨다. 하지만 나는 코드를 길게 작성해야 하고 문자열이 아닌 다른 자료형으로 사용 시 파싱 작업도 해야하는 번거로움 때문에 이전에 알고 있었던 Scanner 클래스를 주로 사용하곤 했다. 그런데 문득 두 클래스의 차이점이 과연 무엇인지 의문이 들기 시작했다.
분명 장단점이 있을텐데 어떤 클래스를 어떤 상황에서 사용하는게 좋을까?
더 확실한 이해를 위해 두 클래스의 차이점을 기록으로 남겨 보려고 한다.
Scanner
Scanner 클래스는 입력받은 데이터를 다양한 타입으로 변환하여 반환하는 클래스 이다. 간단하게 기본형과 String 타입을 정규표현식을 이용해 파싱할 수 있다.
현재 내가 파악하고 있는 Scanner의 특징은 이렇다.
- java.util 패키지에 속하는 클래스이다.
- 직관적이고 사용이 편리하다.
- 공백이나 개행을 기준으로 데이터를 구분하여 읽는다(" ", "\t", "\r", "\n" 등)
- 원하는 타입으로 손쉽게 파싱하여 반환해준다.
- 데이터를 입력받을 경우 즉시 사용하에게 전송 되며 입력받을 때마다 전송되어야 하기에 많은 시간이 소요된다.
BufferedReader
BufferedReader는 데이터를 읽어와 8192 byte 크기의 버퍼에 보관한 후 버퍼에서 데이터를 읽어오는 방식으로 동작하는 클래스이다.
여기서 버퍼(buffer)란 데이터를 다른곳으로 전송하는 동안 임시로 데이터를 보관하는 임시 메모리 영역이다. 주로 입력이나 출력의 속도 향상을 위해 버퍼를 사용하며 자바에서는 BufferedReader와 BufferedWrite 클래스를 이용하여 다룰 수 있다.
BufferedReader의 특징은 다음과 같다.
- java.io 패키지에 속하는 클래스이다.
- 데이터를 파싱하지 않고 String 타입으로만 읽고 반환한다.
- 반드시 예외처리를 명시해야 한다.
- 버퍼가 가득차거나 개행이 일어날 시 버퍼의 데이터를 한번에 프로그램에 전달하여 속도가 빠르다.
Scanner와 BufferedReader의 차이
특징만 보면 Scanner가 BufferedReader보다 직관적이고 사용하기 쉽고 입력을 즉시 전송하기 때문에 더 효율적이라고 생각이 들 수 있지만 처리하는 CPU의 성능에 따라 전송 속도가 천차만별일 수 있기 때문에 버퍼를 사용하는 방식이 더 빠르다고 할 수 있다.
버퍼를 쉽게 예로 들면 A에서 B로 물건을 하나씩 건내 주는 것 보다 수레에 실어서 한번에 전달하는 방식이라고 보면 된다.
좀 더 자세한 차이점을 말하자면
BufferedReader보다 좋은 Scanner의 장점
- String 타입으로만 반환할 수 있는 BufferedReader에 비해 원하는 타입으로 읽고 파싱하여 반환하기 때문에 따로 파싱 작업 없이 int, long, short, float, double로도 반환이 가능하다.
- 코드가 간결하고 직관적이므로 사용이 편하며 예외처리를 따로 해줄 필요가 없다.
- 개행뿐만 아니라 공백을 통해서도 구분하여 입력된다.
Scanner보다 좋은 BufferedReader의 장점
- 버퍼의 사용으로 CPU가 하나하나 입출력을 하는 것이 아닌 버퍼에 쌓아두고 개행이 일어날 때마다 입출력을 처리하기에 Scanner보다 빠른 실행속도를 보여주고 더욱 효율적인 메모리 용량(8KB)을 가진다.
- Thread safe 성질을 지니고 있기에 멀티스레드 환경에서도 안전한 특징을 가진다.
Scanner의 사용
Scanner 클래스의 사용 방법은 다음과 같다.
package practice; // Scanner 클래스 호출
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); // Scanner 객체 생성
String str = sc.nextLine(); // Scanner의 사용
}
}
1. 먼저 Scanner 사용을 위해 java.util 패키지를 import 해준다.
2. System.in을 통해 Scanner 객체를 생성해 준다.
3. nextLine() 메소드를 통해 입력을 받은 데이터를 String타입으로 str에 저장한다.
Scanner 클래스는 다양한 입력 메소드를 가지는데 해당 메소드들을 통해 다양한 타입으로 반환이 가능하다.
nextByte() | byte형 입력 및 반환 |
nextShort() | short형 입력 및 반환 |
nextInt() | int형 입력 및 반환 |
nextLong() | long형 입력 및 반환 |
nextFloat() | float형 입력 및 반환 |
nextDouble() | double형 입력 및 반환 |
nextBoolean() | boolean형 입력 및 반환 |
next() | String형 입력 및 반환 (공백을 기준으로 단어 구분) |
nextLine() | String형 입력 및 반환 (개행을 기준으로 한줄 구분) |
BufferedReader의 사용
BufferedReader의 사용법은 다음과 같다.
package practice;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
int num = Integer.parseInt(br.readLine());
}
}
1. 먼저 java.io 패키지를 import 해준다.
2. 예외처리를 위해 IOException을 throws 해준다. (BufferedReader를 사용 시 꼭 필요하다.)
3. InputStreamReader를 매개변수로 객채를 생성해준다.
4. readLine() 메서드로 문자열을 입력받아 반환하여 사용한다.
여기서 중요한 점은 무조건 문자열로 반환하기 때문에 다른 타입으로 반환이 필요한 경우 파싱작업이 꼭 필요하다는 점이다. 위의 Scanner보다 더욱 긴 코드를 보여주지만 실행 시간은 더 빠른 것이 특징이다.
그래서 어떤게 더 좋은걸까?
개인적으로 공부를 하며 느낀 점은 두 클래스 중 어느 하나가 무조건 좋다고는 할 수 없다는 것이었다.
코드의 직관성과 적은 입력을 받을 상황에서는 간단하게 Scanner를 사용하면 되고
많은 입력을 받는 상황에 실행속도가 중요한 상황이면 BufferedReader를 사용하면 될 것 같다는 생각이다.
사실 Scanner의 사용이 무조건적으로 편한 것은 맞지만 상황에 따라서는 개발자의 편의보다 사용자의 사용성이 더 중요한 순간이 많지 않을까라는 생각이 들었다.
'개발 > JAVA' 카테고리의 다른 글
[JAVA/자바] 개인 미니 프로젝트 - 호텔 예약 시스템 (0) | 2025.01.29 |
---|---|
[JAVA/자바] 배열과 리스트 (1) | 2025.01.18 |
[JAVA/자바] StringTokenizer 문자열 분리 (1) | 2024.12.28 |