프로그래밍 공부/Java

[GPT 질문] Scanner보다 BufferedReader가 좋아?

내 머리속 어딘가 2025. 5. 5. 18:32
반응형

나의 말:

java에서 입력을 받을때 왜 Scanner보다 BufferedReader가 왜 더 좋아?


ChatGPT의 말:

좋은 질문이에요! Java에서 입력을 받을 때 Scanner보다 BufferedReader가 더 좋다고 평가되는 이유는 주로 성능과 유연성 때문입니다. 아래에 비교해서 정리해볼게요.


✅ BufferedReader vs Scanner: 차이점 비교

항목  BufferedReader  Scanner
성능 빠름 (버퍼 사용) 느림 (내부에서 정규표현식 사용)
기반 클래스 Reader 기반 (주로 InputStreamReader) Readable 기반
입력 단위 한 줄(readLine()), 문자 토큰 단위 (next(), nextInt() 등)
파싱 기능 없음 (직접 파싱 필요) 있음 (nextInt(), nextDouble() 등 내장)
입력 예외 처리 IOException 필수 처리 NoSuchElementException, InputMismatchException 등
줄바꿈 처리 명시적으로 처리 자동 처리 가능

🔍 BufferedReader가 더 나은 상황

  • 대량의 데이터를 빠르게 입력받을 때 (예: 알고리즘 문제 풀이)
  • 성능이 중요한 경우 (예: 온라인 저지, 백준)
  • 입력을 줄 단위로 받고, 직접 파싱이 가능한 경우
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine(); // 한 줄 입력
int number = Integer.parseInt(input); // 직접 파싱

🔍 Scanner가 더 편한 상황

  • 입력이 많지 않거나 복잡하지 않을 때
  • 간단한 입력으로 빠르게 테스트할 때
  • 토큰 단위 입력 처리가 필요한 경우
Scanner sc = new Scanner(System.in);
int number = sc.nextInt();  // 자동으로 int로 파싱해줌

🧠 요약

  • BufferedReader는 빠르지만 불편 (직접 파싱 필요)
  • Scanner는 편하지만 느림 (정규표현식 사용 때문)

그래서 알고리즘 문제나 대량 입력이 필요할 땐 BufferedReader를 추천합니다!
 


나의 말:

근데 BufferedReader를 이용하고 StringTokenizer를 이용해서 또 분리하고 Parsing까지 하는데 Scanner보다 빨라?


 

ChatGPT의 말:

네, 맞습니다.
BufferedReader + StringTokenizer 조합이 Scanner보다 확실히 빠릅니다.
심지어 StringTokenizer 없이 split()을 써도 대부분의 경우 Scanner보다 빠릅니다.
왜 그럴까요? 이유는 다음과 같습니다:


🔍 Scanner가 느린 이유

  • Scanner는 정규표현식(Regex) 기반으로 동작합니다.
  • nextInt(), next() 같은 메서드는 내부적으로 패턴 매칭을 수행하므로 처리 속도가 느립니다.
  • 또한 입력마다 버퍼를 체크하기 때문에 반복적으로 I/O 작업이 발생하면 더 느려집니다.

⚡ BufferedReader + StringTokenizer가 빠른 이유

  • BufferedReader는 한 줄을 통째로 읽기 때문에 I/O를 최소화합니다.
  • StringTokenizer는 단순히 구분자를 기준으로 빠르게 문자열을 자르기만 하기 때문에 매우 가볍습니다. (정규표현식 사용 안 함)
  • Integer.parseInt()로 직접 파싱하면 오버헤드가 거의 없습니다.

📊 예시 비교

// 빠름
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
StringTokenizer st = new StringTokenizer(line);
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
// 느림
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();

위와 같이 같은 작업을 해도 BufferedReader + StringTokenizer 조합이 훨씬 빠릅니다.


✅ 결론

  • 알고리즘 문제, 대량 입력 처리 시는 BufferedReader + StringTokenizer를 쓰는 게 더 빠름
  • Scanner는 간단한 프로그램이나 실습 용도에는 사용하기 편하지만, 성능은 떨어짐

나의 말:

근데 BufferedReader에서는 IOException을 고려해야되지?


ChatGPT의 말:

맞습니다. BufferedReader를 사용할 때는 반드시 IOException을 처리해야 합니다.
이는 BufferedReader의 readLine() 메서드가 checked exception인 IOException을 던지기 때문입니다.


🔧 처리 방법 2가지

1. throws로 예외를 위임

public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String line = br.readLine(); // 예외 발생 가능
    System.out.println(line);
}

→ 간단한 테스트용 코드에 적합. 예외 처리를 생략하고 싶을 때 사용.


2. try-catch로 직접 처리

public static void main(String[] args) {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    try {
        String line = br.readLine();
        System.out.println(line);
    } catch (IOException e) {
        System.out.println("입력 중 오류 발생: " + e.getMessage());
    }
}

→ 실무나 안정성이 중요한 코드에서 사용. 예외 상황에 대응 가능.


💡 참고: Scanner는?

Scanner는 IOException을 unchecked exception으로 감싸기 때문에 try-catch가 필수는 아닙니다.
이 점 때문에 초보자들이 편하게 느끼는 경우도 많죠.


✅ 정리

항목  BufferedReader  Scanner
예외 처리 IOException 필수 (throws 또는 try-catch) 생략 가능 (내부 처리됨)
초보자 친화도 낮음 (예외 처리 필요) 높음 (예외 처리 생략 가능)

예외 처리가 번거롭긴 해도, 성능이 중요한 경우 BufferedReader + 예외 처리 코드는 감수할 만한 가치가 있습니다.


나의 말:

BufferedReader 쓸때 IOException 말고 더 신경쓸게 있어?


ChatGPT의 말:

아, 정확한 의도 파악했어요. BufferedReader를 사용할 때 IOException 외에 개발자가 특별히 더 신경 써야 할 요소들을 아래에 정리해볼게요. 꽤 중요한 포인트들이 있습니다.


✅ BufferedReader 사용 시 IOException 외에 신경 써야 할 요소

1. null 반환 처리

  • br.readLine()은 더 이상 읽을 줄이 없으면 null을 반환합니다.
  • 이걸 체크하지 않으면 NullPointerException이 발생할 수 있어요.
String line;
while ((line = br.readLine()) != null) {
    // 반드시 null 체크 필요
}

2. 숫자, 문자 등 파싱 실패 (NumberFormatException 등)

  • readLine()은 항상 String으로 반환하기 때문에, 형 변환 시 예외가 발생할 수 있어요.
  • 예: Integer.parseInt(), Double.parseDouble() 등
try {
    int num = Integer.parseInt(br.readLine());
} catch (NumberFormatException e) {
    System.out.println("잘못된 숫자 형식입니다.");
}

3. 버퍼 비움/flush 불필요하나 close()는 명시적 호출 필요

  • BufferedReader는 출력 스트림이 아니라 flush()는 의미 없지만, 사용이 끝나면 반드시 close() 호출이 필요해요 (특히 파일/네트워크 기반이면 자원 누수 발생 가능)
br.close(); // System.in 기반이라면 생략 가능하지만, 명시적으로 해두는 게 좋음

4. 읽은 문자열의 앞뒤 공백 주의

  • 사용자가 입력한 값에 공백이 포함될 수 있으므로 .trim()을 사용하는 것이 안전합니다.
String input = br.readLine().trim();

5. 한 줄 입력에 여러 값이 있는 경우 직접 파싱 필요

  • Scanner처럼 nextInt() 등이 없으므로, 한 줄에 여러 값이 있을 경우 split() 또는 StringTokenizer로 직접 나누고 파싱해야 해요.
String[] parts = br.readLine().split(" ");
int a = Integer.parseInt(parts[0]);
int b = Integer.parseInt(parts[1]);

또는:

StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());

6. 입력 인코딩 문제 (특히 파일/네트워크 입력 시)

  • 시스템 기본 인코딩과 실제 인코딩이 다를 수 있음 (예: UTF-8 vs EUC-KR)
  • InputStreamReader에 인코딩을 명시하는 것이 바람직합니다.
BufferedReader br = new BufferedReader(
    new InputStreamReader(System.in, StandardCharsets.UTF_8));

🧠 핵심 체크리스트 요약

항목 설명
null 체크 EOF 시 readLine()이 null 반환
형 변환 실패 parseInt(), parseDouble() → NumberFormatException 가능
공백 제거 입력 앞뒤 공백 .trim() 처리
여러 값 파싱 split() 또는 StringTokenizer 사용 필요
자원 정리 close() 명시적으로 호출
인코딩 명시 파일/외부 입력 시 인코딩 오류 방지

 
 
 


추가 자료:

https://juno-juno.tistory.com/99

 

Scanner와 BufferedReader / BufferedWriter의 차이점과 사용법

이때까지 귀찮아서 Scanner만 항상 사용했는데, 이제야 정리를 해보고, 오늘 부로 절대 Scanner를 사용하는 과거로 돌아가지 않을 것이다. 1. Scanner Scanner는 띄어쓰기와 개행문자를 경계로 값을 인식

juno-juno.tistory.com

https://itbeginner2020.tistory.com/27

 

BufferedReader의 readLine() 은 왜 throws Exception 해주어야할까?

위와같이 main 에 throws Exception 해주지 않거나 try-catch 로 예외처리 하지 않으면 readLine() 메서드에 에러가 나는 이유가 갑자기 궁금해져 집요하게 파보았다. 사실 이런건 왜 발생하는가 보다 발생

itbeginner2020.tistory.com

https://cheese10yun.github.io/checked-exception/

 

Checked Exception을 대하는 자세

Checked Exception을 처리하는 전략과 그것에 유의해야 할 점들에 대해서 포스팅을 진행해보겠습니다. 자바에서는 대표적으로 Checked Exception 과 Unchecked Exception이 있습니다. 먼저 이 둘의 차이를 살펴

cheese10yun.github.io

https://jamesdreaming.tistory.com/126

 

[ 자바 코딩 ] NumberFormatException 원인과 해결방법

안녕하세요. 제임스 입니다. 이번에는 개발 중 종종 발생하는 오류중 하나인 NumbreFormatException 에 대해 정리 해보겠습니다. NumbreFormatException 은 왜 발생 하는 것일 까요? 단어를 잘 보시면 이유를

jamesdreaming.tistory.com

 

반응형