언어/JAVA

[자바/Java] 입력 비교 Scanner, BufferedReader

gyungmean 2024. 1. 19. 11:24

알고리즘 문제 풀이를 하다보니 Java를 사용하는 사람들이 대부분 Scanner대신 BufferedRedaer를 사용하여서

둘의 차이가 무엇인지 정리해두는 글을 작성하려고 한다.

Scanner

  • java.util.패키지에 속하고
  • primitive types과 String을 파싱해주는 텍스트 스캐너이다.
  • 공백과 개행을 기준으로 읽는다.
  • nextInt()같이 원하는 자료형으로 입력을 받는 것도 가능하다.
  • 입력 받은 동시에 사용자에게 전달한다.
  • 위의 두 이유로 scanner를 사용해서 입력을 받으면 시간이 오래 걸리게 된다.
  • 멀티쓰레드 상에서 보안 이슈가 많다.
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
double c = sc.nextDouble();
String str = sc.nextln();
sc.close();

BufferedReader

  • java.io 패키지에 속한다.
  • 데이터를 파싱하지 않고 String으로 읽고 가져온다.
  • 반드시 예외 처리를 명시해야한다.I/O Exception을 throw하거나 try/catch 해야한다.
  • readLine()메소드 하나만을 사용해서 읽는다.
  • 멀티스레드 환경에서도 안전하다.
  • 버퍼가 가득차거나 개행문자가 나타나면 한번에 프로그램으로 전달하기에 입력양이 많을때 편리하다.
BufferedReader in = new BufferedReader(new FileReader("foo.in"));

도큐먼트에 나와있는 예시는 위와 같은데

알고리즘 문제를 풀때는 보통 InputStreamReader를 많이 사용했다.

BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(bf.readLine());

그렇다면 InputStream은 무엇인가?

스트림은 데이터의 흐름을 의미하는 것이고
InputStream은 데이터가 입력되는 흐름이라고 할 수 있다. java.io의 클래스이며 OutputStream과 함께
byte 단위 입출력을 위한 최상위 스트림 클래스이다.

 

아무튼 입력을 받은 것을 이제 어떻게 사용하냐.

 

Split

for(int i = 0; i < n; i++) {
			String tmp = bf.readLine();
			String[] tmp_arr = tmp.split(" ");
			edges[i][0] = Integer.parseInt(tmp_arr[0]);
			edges[i][1] = Integer.parseInt(tmp_arr[1]);
}

위 코드는 한줄에 1 0 과 같이 한칸 공백띄고 서로를 연결하는 노드를 표시하는게 입력된 후의 모습이다.

bf.readLine()으로 한줄을 읽어와서 split(" ")으로 개행문자가 아닌 공백 문자를 분리해준다.

 

 

StringTokneizer

StringTokenizer st = new StringTokenizer(br.readLine());
int m = Integer.parseInt(st.nextToken());
int n = Integer.parseInt(st.nextToken());

StringTokenizer는 String을 Token단위로 끊어준다.

java.util 패키지를 임포트 해야한다.

공백말고도 따로 delimiter를 지정해줄 수도 있다.