[JAVA] Scanner & Buffer

신피질의 재앙·2022년 5월 4일
0

지금까지 문제에서 입력을 사용하기 위해 Scanner로 입력을 받았다.
하지만, 빠른 A+B(15552번) 문제를 보면
Java는 Buffer를 사용하라는 조건이 있다.

이는 데이터의 양이 많을 때
Scanner가 실행속도 느리고 여러가지 정규식을 검증한다고 하여
빠른 A+B와 같은 문제를 풀이하려면
Buffer를 사용하라는 문제였다.

[참고글]
https://carpediem0212.tistory.com/11

참고글에서 InputStreamReader에 대해 먼저 설명하는데
이는 문자열(String)을 Character(한 글자 단위)로 읽어들인다.

InputStreamReader는 한 글자씩 문자열을 읽어들여서 긴 문자열을 읽어 들일 때
비효율 적이라고 한다.
이 점을 보완하기 위해 BufferedReader가 있다.

BufferedReader

InputStreamReader에 버퍼링이 추가된 Class이다.
사용자가 요청할 때마다 데이터를 읽어오는 것이 아닌 일정한 크기의 데이터를 한번에 읽어와 버퍼에 보관한 후 버퍼에서 데이터를 읽어오는 방식으로 동작한다.

그렇기 때문에 속도가 향상되고 시간의 부하가 적다는 장점이 있다.
입력을 라인단위로 입력 받기 때문에 공백의 경우에도 String으로 인식하여 받아들이며, 입력받은 데이터 타입이 String 타입이므로 다른 타입의 데이터라면 이후 형 변환이 필요하다는 특징이 있다.

Scanner

Scanner는 Java1.5 부터 util패키지 내에 포함된 Class이며,
공란과 줄바꿈을 모두 입력값의 경계로 인식하기 때문에
쉽게 데이터를 입력받을 수 있도록 해준다.

비교

BufferedReader는 Scanner에 비해 더 큰 Buffer Size를 가지고 있다.
Scanner는 문자열 파싱 기능이 제공되는 반면에 BufferedReader는 단순히 읽어 들인다는 차이도 존재한다.

하여 Buffered Reader가 빠르다


2741번 문제를 Scanner(1108ms)와 Buffer(296ms)로 풀이한 것
확연한 차이를 볼 수 있다.

Buffer의 사용법과 기능

[참고글]
https://m.blog.naver.com/ka28/221850826909

BufferedReader : Scanner
BufferedWriter : System.out.println(); 과 같은 기능을 한다고 한다.

이를 사용하기 위해선

다음의 import가 추가적으로 필요하다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

참고글에서 알려주신대로 class 내에서 선언을 하게 되면 밑줄이 생성되는데
Ctrl + Shift + o를 하면 eclipse가 자동으로 제시해준다고 한다.

** BufferedReader 사용법

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine(); // string
int i = Integer.parseInt(br.readLine()); // Int

선언은 위와 같이 한다고 한다 (참고 글에선 bf로 했지만 br이 더 보편적인 것 같다.)
입력은 readLine();이라는 메서드를 활용한다. 이때 주의할 점은 2가지 있다.

첫번째, readLine()은 return값을 String으로 고정하기에
String이 아닌 다른 type으로 입력을 받으려면 형 변환을 꼭 해주어야한다.

두번째, 예외처리를 꼭 해주어야한다. readLine을 할 때마다 try & catch를 활용하여 예외처리를 해주어도 되지만 대개 throws IOException을 통해 작업한다.

** 입출력 예외처리를 위한 throws IOException

Import java.io.IOException; 

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

(1) 같이 클래스를 import 해주고
(2) Main 클래스에서 throws IOException을 작성한다.

** readLine() 사용 시 라인 단위로 값을 받아오기 때문에, StringTokenizer, split 이용

StringTokenizer st = new StringTokenizer(s); 
int a = Integer.parseInt(st.nextToken());
int b = integer.paresInt(st.nextToken());

String array[] = s.split(" ");

(1) StringTokenizer 인자 값에 입력 문자열을 넣음
(2, 3) 첫번째 두번째 호출
(4) 공백마다 데이터를 끊어서 배열에 넣음

첫번째 방법은 StringTokenizer에 nextToken()함수를 쓰면 readLine()을 통해
이벽받은 값을 공백단위로 구분하여 순서대로 호출
두번째 방법은 String.split()함수를 활용하여 배열에 공백 단위로 끊어서
데이터를 넣고 사용하는 방식이다.

** BufferedWriter 사용법

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String s = "abc"; 
bw.write(s+"\n");
bw.flush();
bw.close();

BufferedWriter와 같은 경우 버퍼를 잡아놓았기 때문에 flush() / close()를 반드시 호출에 주어 뒤처리를 해주어야 한다.
bw.write는 System.out.println();과 같이 자동개행이 되지 않아
\n 이스케이프 시퀸스를 사용하여야 한다.

0개의 댓글