BufferedReader 와 Scanner

작성일     업데이트:

카테고리:

태그:

BufferedReader 와 Scanner 차이점

1. 속도

BufferedReader는 일정한 크기의 데이터를 한번에 읽어와 버퍼에 보관 한 후, 사용자의 요청이 있을 때 버퍼에서 데이터를 읽어오는 방식이고
Scanner는 입력마다 하나하나 바로 전송이 되기때문에 속도차이가 나는 편이다.
따라서 상대적으로 BufferedReader쪽이 더 빠른 편이다.

2. 활용

Scanner는 int, short, long, float, double, String 값을 각각 읽어들일 수 있다.
하지만 BufferedReader는 문자열인 String 값 밖에 읽지 못한다.
따라서 입력된 데이터를 가공하기엔 Scanner 쪽이 더 편리한 편이다.


BufferedReader 사용법

-사용예시-

// 예외처리
import java.io.IOException;
// 입력처리
import java.io.BufferedReader;
import java.io.InputStreamReader;
// 출력처리
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;

public class Main {
    public static void main(String[] args) throws IOException {

      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

      String in = br.readLine(); // String 형태 + 행 단위로 입력값을 받아옴

      bw.write(in); // 출력값을 buffer에 저장
      bw.flush(); // 출력
      bw.close(); // 출력 및 출력 stream 닫기
    }


1. 예외처리 하기 (택1)

  • IOException을 import 하여 main 클래스 옆에 throws IOException을 사용하는 방식
  • try-catch문을 사용하여 예외처리를 해주는 방식

자바는 입출력 시 발생할 수 있는 예외에 대해 까다롭게 규정되어있기 때문에 이러한 것을 다루는 메서드에 예외처리가 없다면 컴파일 에러가 발생하게 된다.
그중 IOExceptioncheckedException이기 때문에 반드시 예외처리가 필요하며 인풋값이 null일 경우 등의 장애를 대비하기 위해서라도 미리 예외처리가 필요하다.
예외적으로 print(), println(), printf()는 자체적으로 예외처리가 되어있기 때문에 따로 처리가 필요 없다고 한다.


2. import 해오기

위 예시 코드처럼 각기 따로 import해주어도 되고 import java.io.*;로 한번에 진행해도 된다.


3. 데이터 사용

readLine()을 사용하여 String 형태로 저장된 데이터를 불러오는데 readLine()은 행(Line)단위(=Enter단위)로만 데이터를 받을 수 있다.
readLine()으로 받아온 한 줄의 행 안에서 공백 등으로 또다시 데이터를 가공하고자 한다면 StringTokenizer 또는 split() 등을 사용하여 별도의 가공처리가 필요하다.


4. + BufferedWriter

BufferedWriterSystem.out.println()과 비슷한 역할을 하지만 리소스가 더 적게 든다고 한다.
write()로 출력값을 버퍼에 저장해두었다가 flush()close() 되었을 때 한번에 출력 stream에 반영시킨다.
close()는 아예 stream을 닫아버리는 것이니 사용시 주의가 필요하다.


Scanner 사용법

-사용예시-

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

      Scanner in = new Scanner(System.in);

      byte a = in.nextByte(); // byte 형 입력 및 리턴
      short b = in.nextShort(); // short 형 입력 및 리턴
      int c = in.nextInt(); // int 형 입력 및 리턴
      long d = in.nextLong(); // long 형 입력 및 리턴

      float e = in.nextFloat(); // float 형 입력 및 리턴
      double f = in.nextDouble(); // double 형 입력 및 리턴

      boolean g = in.nextBoolean(); // boolean 형 입력 및 리턴

      String h = in.next(); // String 형 입력 및 리턴 (공백을 기준으로 한 단어를 읽음)
      String i = in.nextLine(); // String 형 입력 및 리턴 (개행을 기준으로 한 줄을 읽음)
    }


1. import 해오기

import java.util.Scanner;로 import를 해주어야 한다.


2. 데이터 사용

위의 예시들처럼 다양한 형태로 입력값을 받아올 수 있으며 상황에 맞게 코드를 사용하면 된다.
다만 next()nextLine()의 차이를 제대로 이해하고 쓰지 않으면 원하지 않는 결과가 도출될 수 있기 때문에 주의가 필요하다.


3. next()nextLine()의 차이

  • next() : ‘공백 기준 한 단어’를 읽는 메소드로 공백을 기준으로 문장 한개(= 한 단어)만 읽어들인다.
  • nextLine() : ‘개행 기준 한 줄’을 읽는 메소드로 개행(엔터)을 기준으로 한 줄에 입력된 여러 문장(단어)들을 읽는다.

만약 이 둘을 혼용해서 사용한다면 특별한 주의가 필요한데

hello
my
world

위 문장에서 hello를 next()로 불러온 바로 다음에 nextLine()을 사용할 경우

사용자가 원하던 것은 "hello""my"를 각각 불러오는 것이었겠지만 실제 값은 "hello"" "이 되는 식이다.

이건 nextLine() 의 특성 때문인데 개행(엔터) 기준 한줄을 읽어오기 때문에 "hello" 바로 뒤에 입력했던 개행(엔터)가 남아있는 것을 인식하고 그 줄을 읽어버린 후 넘어간 것이다.

이런 현상을 피해가기 위해서는 next()nextLine() 사이에 한번 더 nextLine()을 추가해주어야 한다.

댓글남기기