[Java] BufferedReader, Scanner, StringTokenizer

Blair·2023년 12월 12일
1

Java

목록 보기
1/4
post-thumbnail

프로그래머스 level0을 떼고 🎉, 다양한 유형의 코테를 풀어보고자 백준 문제를 풀기 시작했다.
풀다 보니 프로그래머스 문제들과는 다르게 직접 값을 입력 입력 받아 코드를 짜야하는 문제들이 많았다! 이참에 기본적인 내용들을 정리하고 넘어가보자!! 💪🏻

BufferedReader

BufferedReader는 버퍼를 사용하여 읽기와 쓰기를 하는 함수이다.

버퍼를 사용하지 않는 입력: 키보드의 입력이 키를 누르는 즉시 바로 프로그램에 전달됨.
버퍼를 사용하는 입력: 키보드의 입력이 있을 때마다 한 문자씩 버퍼로 전송함. 버퍼가 가득 차거나 혹은 개행 문자가 나타나면 버퍼의 내용을 한 번에 프로그램에 전달한다.

버퍼를 사용하는 것이 더 효율적이고 빠르다?!

한번 버퍼를 거쳐 출력되는 것보다, 키보드의 입력을 받는 즉시 출력하는 것이 더 빠르지 않을까?! 하고 생각할 수 있다.
하드디크스는 속도가 느리다. 그리고 외부장치(키보드, 모니터 등)와 데이터 입출력도 생각보다 시간이 오래 걸린다. 그렇기 때문에 키보드의 입력이 있을 때마다 바로 이동시키는 것보다는, 중간에 버퍼를 두어 한번에 묶어 보내는 것이 더 효율적이고 빠른 방법이다.

쓰레기통을 비우는 일이라고 생각하면 이해가 쉽다. 쓰레기가 생길 때마다 하나하나 밖에 내다버리는 것보다, 쓰레기통에 하나하나 모았다가 꽉 차면 한 번에 모아서 버리는게 훨씬 효율적인 것과 비슷한 개념이라고 생각하면 된다.

Scanner와의 비교

BufferedReaderScanner
개행 문자만 경계로 인식한다.띄어쓰기와 개행문자를 경계로 입력 값을 인식한다.
입력 받은 데이터가 String으로 고정된다. 따라서 입력 받은 데이터를 원하는 타입으로 가공하는 작업이 필요하다.데이터 타입을 따로 가공할 필요가 없다. 지원해주는 메소드가 많고, 사용하기 쉽기 때문에 많이 사용된다.
버퍼 사이즈가 8192 char(16,384 byte)이기 때문에 입력이 많을 때 BufferedReader가 유리하다.버퍼 사이즈가 1024 char이기 때문에 많은 입력을 필요로 할 경우에는 성능상 좋지 못한 결과를 불러온다.
동기와 되기 때문에 멀티 스레드 환경에서 안전하다.동기화가 되지 않기 때문에 멀티 스레드 환경에서 안전하지 않다.
  • Scanner는 띄어쓰기와 개행문자를 경계로 하여 입력 값을 인식한다. 그렇기 때문에 따로 가공할 필요가 없어 편리하다.
    가공할 필요가 없다는 것은, 가령 int형 변수를 입력 받고자 하면 int x = scanner.nextInt()를 하용하여 바로 원하는 타입의 입력을 받을 수 있다는 것이다.

  • 하지만, BufferedReader는 입력 받은 데이터가 String으로 고정된다. 따라서 입력 받은 데이터를 원하는 타입으로 가공하는 작업이 필요하다.

BufferedReader 사용법

1. 선언

BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언
String s = br.readLine();
int i = Integer.parseInt(s);
  • 선언은 위와 같은 방법으로 하면 된다.
  • 입력은 readLine(); 이라는 메소드를 사용한다.
  • String으로 리턴 값이 고정되어 있기 때문에, 다른 타입으로 입력을 받고자 한다면 반드시 형변환이 필요하다.
  • 예외 처리 또한 반드시 필요로 한다. readLine()을 할 때마다 try/catch문으로 감싸주어도 되고, throws IOException을 통한 예외처리를 해도 된다. (후자의 경우가 자주 사용 됨)

2. 데이터 가공 - StringTokenizer, String.split()

BufferedReader를 통해 읽어온 데이터는 개행문자 단위(Line 단위)로 나뉘어진다.
만약 이를 '공백 단위'로 데이터를 가공하고자 하면 따로 작업을 해주어야 한다.
이 때 사용하는 것이 StringTokenizerString.split() 함수이다.

// StringTokenizer
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());

// String.split() 함수
String s = br.readLine();
String arr[] = s.split(" ");

StringTokenizer의 nextToken() 함수를 쓰면 readLine()을 통해 입력 받은 값을 공백 단위로 구분하여 순서대로 호출할 수 있다.
String.spilt() 함수를 사용하면, 배열에 공백 단위로 끊어 데이터를 저장하여 사용할 수 있다.

3. BufferedReader 클래스의 메인 함수들

Modifier and TypeMethod and Description
voidclose()
입력 스트림을 닫고, 사용하던 자원을 해제
voidmark(int, readAheadLimit)
스트림의 현재 위치를 마킹
intread()
한 글자만 읽어 정수형으로 변환(e.g. '3'을 읽어 정수형인 (int)'3' = 51로 반환
StringreadLine()
한 줄을 읽음
booleanready()
입력 스트림이 사용할 준비가 되었는지 확인(1이 준비 완료)
profile
Active 🙌 Curious 🤔 Energetic 💪

0개의 댓글