Post

[Java] Scanner VS BufferedReader

2024-10-16-java-1

알고리즘 문제를 푸는 중 입력 처리에 대해 어떤 문제에 대해서는 Scanner를 사용하고 어떤 문제에서는 BufferedReader 를 사용하여 두 클래스에 차이점을 명확히 이해하기 위해 Scanner와 BufferedReader의 특징과 차이점을 정리하였습니다.

Scanner


Scanner 란?

Scanner 는 Java에서 콘솔이나 파일과 같은 입력 소스로부터 데이터를 읽어오는데 사용되는 클래스입니다. Scanner는 입력을 다양한 데이터 타입으로 변환하는 기능을 제공하며, 공백이나 구분자를 기준으로 데이터를 쉽게 분리하여 처리할 수 있습니다.

Scnnaer 특징

  1. 다양한 데이터 타입 처리: Scanner는 입력을 정수, 실수, 문자열 등 다양한 타입으로 변환할 수 있습니다.
    • 예: nextInt(), nextDouble(), nextLine()
  2. 기본 구분자 사용: 기본적으로 공백을 구분자로 사용하여 입력을 구분하지만, useDelimiter() 메서드를 사용하여 커스텀 구분를 설정할 수 있습니다.
  3. 편리한 콘솔 입력: 콘솔에서 입력을 받아 처리할 때 코드가 직관적이고 간결합니다.
  4. 상대적으로 느린 성능: 입력을 파싱하고 분석하는 기능 때문에, 성능이 상대적으로 느리며, 대용량 데이터를 처리할 때 비효율적일 수 있습니다.
  5. 자동 형변환: 사용자가 명시한 타입으로 자동 형 변환이 이루어집니다. 예를 들어 nextInt() 는 자동으로 정수형으로 입력을 변환합니다.
  6. Thread-unsafe: 멀티스레드 환경에서 안전하지 않습니다.

BufferedReader


BufferedReader 란?

BufferedReader는 문자 입력을 버퍼링하여 효율적으로 읽을 수 있는 클래스입니다. 주로 텍스트 파일이나 네트워크로부터 데이터를 빠르게 읽어오는 데 사용되며, 큰 데이터를 처리할 때 적합합니다.

BufferedReader의 특징

  1. 버퍼링을 통한 성능 향상: BufferedReader는 입력을 버퍼링하여 성능을 높이며, 특히 큰 데이터를 읽을 때 유리합니다.
  2. 한 줄 단위로 입력 처리: BufferedReaderreadLine 메서드를 사용하여 한번에 한 줄씩 입력을 처리합니다.
  3. 단순한 입력 처리: 추가적인 파싱 기능은 제공하지 않으며, 입력된 데이터를 그대로 처리합니다.
  4. IO 예외 처리 필요: BufferedReader는 입력 중에 IOException이 발생할 수 있기 때문에, 예외 처리가 필수적입니다.
  5. 대용량 데이터 처리에 적합: 파일에서 많은 데이터를 읽을 때 적합하며, 대규모 텍스트 파일 처리에 자주 사용됩니다.
  6. Thread-safe: 멀티스레드 환경에서 안전합니다.

버퍼링이란?

데이터를 임시 저장 공간(버퍼, buffer)에 저장하여 입출력 작업을 효율적으로 처리하는 기술로, 특히 입출력(I/O) 작업에서 성능을 향상시키는 데 중요한 역할을 합니다. 버퍼링을 사용하면 입출력 장치의 속도 차이를 보완할 수 있습니다.

Scanner vs BufferedReader


항목ScannerBufferedReader
입력 처리 방식구분자 기반의 다양한 데이터 타입 변환문자열로 한 줄씩 읽음
성능상대적으로 느림버퍼링을 통해 빠름
데이터 타입정수, 실수, 문자열 등 여러 타입 지원문자열만 처리
예외 처리별도의 예외 처리 필요 없음IOException을 처리해야 함
사용 목적콘솔 입력 및 간단한 입력 분석파일, 네트워크 등에서 대용량 데이터 처리
동기화동기화되지 않음동기화되지 않음
구분자 설정기본적으로 공백을 구분자로 사용구분자 사용 불가
버퍼 메모리 용량1KB8KB(많은 입력이 있을 경우 더 효율이지만 큰 메모리를 잡아먹는다)

코드 예제

  • 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
This post is licensed under CC BY 4.0 by the author.