Scanner vs BufferedReader

박민수·2023년 12월 23일
0

Java

목록 보기
1/1
post-thumbnail

처음에 자바 문법을 배울 때 사용자 입력 관련해서는 Scanner를 쓴다고해서 의심없이 쓰고 있었는데, 자료구조/알고리즘 문제들을 풀며 여러 블로그들을 참고하다보니 Scanner보다 BufferedReader를 더 많이 쓰는 것을 알 수 있었다. 큰 차이는 없지만 BufferedReader가 속도면에서 이점을 가지기 때문에 사용한다고 한다.

오늘은 Scanner 클래스와 BufferedReader 클래스에 대해 알아보려고 한다. 각각의 클래스의 사용 방법과 차이점으로는 무엇이 있을까?


Scanner 클래스

Scanner 클래스는 입력 스트림에서 특정 데이터 유형을 읽을 때 사용된다. 주로 토큰(token) 단위로 읽어들이기 때문에 입력 값이 특정 구분자로 나뉘어진 경우에 유용하다. 예를 들면, 기본적으로 공백이나 개행문자로 토큰을 구분한다.

  • 사용법
import java.util.Scanner;

public class ScannerExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 문자열 읽기
        System.out.print("Enter a string: ");
        //next()를 사용해도 되지만 특정 구분자 전까지만 읽어들이기 때문에 다음 줄에 있는 입력을 읽어들이기 위해서는 nextLine()을 사용하고 넘어가야 한다.
        String inputString = scanner.nextLine();
        System.out.println("You entered: " + inputString);

        // 정수 읽기
        System.out.print("Enter an integer: ");
        int inputInt = scanner.nextInt();
        System.out.println("You entered: " + inputInt);

        // 실수 읽기
        System.out.print("Enter a double: ");
        double inputDouble = scanner.nextDouble();
        System.out.println("You entered: " + inputDouble);

        scanner.close();
    }
}

BufferedReader 클래스

BufferedReader 클래스는 문자 스트림에서 데이터를 읽을 때 사용되며, 특히 한 줄씩 데이터를 읽기에 적합하다. 버퍼링을 통해 성능을 향상시키므로 대용량 데이터에 효과적이다.

  • 사용법(1)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BufferedReaderExample {
    public static void main(String[] args) throws IOException {
        // InputStreamReader를 사용하여 System.in의 바이트 스트림을 문자 스트림으로 변환
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 문자열 읽기
        System.out.print("Enter a string: ");
        String inputString = br.readLine();
        System.out.println("You entered: " + inputString);

        // 정수 읽기
        System.out.print("Enter an integer: ");
        int inputInt = Integer.parseInt(br.readLine());
        System.out.println("You entered: " + inputInt);

        // 실수 읽기
        System.out.print("Enter a double: ");
        double inputDouble = Double.parseDouble(br.readLine());
        System.out.println("You entered: " + inputDouble);

        // BufferedReader를 닫음
        br.close();
    }
}
  • 사용법(2)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BufferedReaderMultipleValues {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        System.out.print("Enter multiple values separated by space: ");
        // 한 줄을 읽고, StringTokenizer 등을 사용하여 공백으로 값을 나눌 수 있음
        String[] values = br.readLine().split("\\s+");

        // 값들을 각각의 변수에 할당
        int intValue = Integer.parseInt(values[0]);
        double doubleValue = Double.parseDouble(values[1]);
        String stringValue = values[2];

        System.out.println("Int: " + intValue);
        System.out.println("Double: " + doubleValue);
        System.out.println("String: " + stringValue);

        br.close();
    }
}

BufferedReader 클래스에 대해 알아보던 중 Scanner 클래스와는 달리 선언시에 new InputStreamReader가 들어있는 것을 알 수 있었다. 왜 더 길어지고 복잡해진걸까?

BufferedReader 클래스는 문자 스트림에서 데이터를 읽기 위한 클래스이지만, System.in은 바이트 스트림이다. BufferedReader는 문자 스트림을 대상으로 동작하므로, InputStreamReader를 사용하여 바이트 스트림을 문자 스트림으로 변환해주어야 한다.

InputStreamReader는 바이트 스트림을 문자 스트림으로 변환하는 역할을 한다. 따라서 BufferedReader를 생성할 때 InputStreamReader의 인스턴스를 생성해 주면 바이트 스트림에서 문자 스트림으로의 변환을 처리할 수 있게 된다.


Scanner vs BufferedReader

두 클래스 간에 엄청 큰 차이를 보이지는 않지만 다음과 같은 성능 차이를 보인다고 한다.

Scanner는 복잡한 데이터 타입을 처리하고 다양한 메서드를 통해 데이터를 읽기 때문에 상대적으로 느리다. 반면에, BufferedReader는 버퍼링을 통해 한 번에 여러 문자를 읽고, readLine() 메서드를 사용하여 한 줄을 읽기 때문에 성능상의 이점이 있다.

여기서 버퍼링이란 무엇일까?

버퍼링은 데이터를 일시적으로 저장하는 임시 공간(버퍼)을 의미한다. 입출력 작업에서는 데이터를 한 번에 처리하는 것이 효율적이지만, 실제로는 데이터가 작은 조각으로 나누어져 들어오거나 나가는 경우가 많다. 이때 이 작은 데이터를 모아서 한 번에 처리하기 위해 버퍼를 사용한다.

Scanner 클래스는 주로 간편한 입력 파싱을 제공하기 위해 설계되었으며, 내부적으로는 데이터를 조금씩 읽어오면서 필요한 파싱 작업을 수행한다. 그러나 입력을 한 번에 많이 읽지 않고 조각조각 읽는 동작이 발생하기 때문에 특히 대량의 데이터를 처리할 때 효율성이 낮다.

반면에 BufferedReader 클래스는 버퍼링을 통해 한 번에 많은 양의 데이터를 읽어오므로 입출력 성능이 향상된다. 특히 코딩 테스트에서는 대체로 대량의 데이터를 처리해야 하는 경우가 많으므로, BufferedReader가 선호되는 경우가 많다.

참고 : https://sorjfkrh5078.tistory.com/93

profile
머릿속에 떠도는 방대한 개발 지식

0개의 댓글