[Java] Scanner, InputStream, InputStreamReader, BufferedReader 가볍게 파헤치기~!

승제·2021년 5월 27일
0

java

목록 보기
1/1

백준의 알고리즘 문제를 풀면서 시간제한 조건이 추가되었다 시간 기준을 맞추는 방법은 여러 가지가 있었지만, 아직 낮은 레벨의 문제를 풀고 있는 나에게는 Scanner를 대체하라는 조언이 많았고 Scanner와 BufferdReader차이를 공부해보려고 한다

본론
1.InputStream (System.in은 무엇인가?)
2.Scanner(System.in)과 InputStreamReader
3.BufferedReader()

InputStream ( System.in ) / System.in은 무엇인가?

InputStream 가장 기본이 되는 입출력 class로써 System Class의 in은 InputStream Type이다

InputStream이란?
가장 기본적인 입력 스트림으로 바이트 단위의 데이터를 보내며, InputStream의 입력 메서드인 read()는 1byte 단위로 읽어드린다. 때문에 2byte 이상의 문자는 1byte만 읽어드리고 나머지는 스트림에 잔존하게 된다

Scanner ( System.in ) 과 InputStreamReader

Scanner는 InputStream type의 System.in을 왜 파라미터로 받는 걸까?

Scanner class를 살펴보면 오버 로딩된 여러 생성자를 볼 수 있는데, 우리는 아래 생성자를 확인하면 된다

public Scanner(InputStream source) { 
    this(new InputStreamReader(source), WHITESPACE_PATTERN); 
}

위 생성자를 확인해보면 InputStreamReader 생성하는 걸 볼 수 있다 앞서 InputStream 한계를 설명한 걸 보면, 1byte만 읽을 수 있기 때문에 문자를 원활하게 표현하려면 확장된 InputStreamReader가 필요하다

JAVA API에서 찾아보면 InputStreamReader는 InputStream의 바이트 단위로 읽어 들이는 형식을 문자 단위 데이터로 변환시키는 중개자 역할을 한다고 한다 ( 바이트 데이터를 문자 단위로 변환하는 것은 Charset이라는 클래스에서 담당한다. 이 클래스 덕분에 UTF-8에서 한글이 3byte여도 2byte로 변환되어 자바 메모리상에서 char 타임에 한글이 대입될 수 있는 것이다)

BufferdReader( new InputStreamReader )

InputStream에서 InputStreamReader로 확장하여, char type을 처리할 수 있도록 확장되었지만 문자열을 사용할 순 없다 그래서 Buffer(버퍼)를 통해 입력받은 문자를 쌓아둔 뒤 한 번에 문자열처럼 보내버리는 BufferdReader가 필요하다

BufferdReader에서 readLine()을 통해 한 줄 전체를(공백 포함) 읽기 때문에 char 배열을 하나하나 생성할 필요 없이 String으로 리턴하여 바로 받을 수 있다

—— 총정리 ——-
Byte Type = InputStream
Char Type = InputStreamReader
Char Type의 직렬화 or String Type = BufferedReader

* InputStream은 바이트 단위로 데이터를 처리한다 또한  System.in의 타입도 InputStream 이다
* InputStreamReader는 문자 단위로 데이터를 처리할 수 있도록 돕는다. InputStream의 데이터를 문자로 변환하는 중개 역할을 한다.
* BufferedReader 은 스트림에 버퍼를 두어 문자를 버퍼에 일정 정도 저장해둔 귀 한 번에 보낸다

Scanner( System.in )가 상대적으로 느린 이유

Scanner class를 살펴보면 입력받은 문자를 해당 메서드로 보내서 정규식들을 검사하고 검사된 문자열을 반환하는 buildIntegerPatternString() 메서드가 있는데, 불필요할 정도로 많은 정규식을 검사하기 때문에 속도가 느리다

참고 사이트
1.https://docs.oracle.com/javase/8/docs/api/java/io/InputStreamReader.html#InputStreamReader-java.io.InputStream-java.nio.charset.Charset-

2. https://st-lab.tistory.com/41#recentEntries

profile
nullnull한 개발자 입니다

0개의 댓글