Java 정리 #1 Scanner vs Buffer

ims·2020년 7월 31일
0

Java 정리 !

목록 보기
1/16
post-thumbnail

✍ Scanner & Buffer

Scanner

import java.util.Scanner;

public class scratchPad {
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        int input = sc.nextInt();
        System.out.println(input);
    }
}

숫자를 입력 받고 싶을 때 위와 같이 Scanner를 사용해서 편리하게 값을 입력받을 수 있다.
그러나 Scanner는 사용하기 편리하지만 느리다는 치명적인 단점이 있다. 그래서 input 값이 작을 때는 Scanner를 사용하기도 하나 data가 많아졌을 때는 필히 Buffer를 사용해야 한다.

Buffer을 사용하는 이유

하드디스크의 속도는 매우 느리다.
또한 하드디스크 뿐 아니라 키보드,모니터와 같은 외부장치의 속도는 시간이 많이 걸리는 작업이다.
고로 버퍼링없이 키보드가 눌릴 때마다 눌린 정보를 바로 목적지로 이동시켜주는 것보다 중간에 Memory Buffer를 두어서 data를 한데 묶어서 이동시키는 것이 효율적이고 빠르다.
그냥 전송하게 되면 Cpu와 성능 차이가 많이 나서 비효율적이다.

Scanner vs Buffer

비유적으로 말하자면
버스에 한 사람 한 사람 태우고 옮기냐 vs 버스에 여러사람 올 때까지 기다렸다가 한 번에 옮기냐 이다.
스캐너는 입력될 때마다 "잠깐 모두 멈춰! 나 얘 입력받을거야!" 하는 것이고 ,
버퍼는 모으고 모으다가 모두 멈춰! 하는것이다.

Buffer

BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //선언
String s = br.readLine(); //String
int i = Integer.parseInt(br.readLine()); //Int
  1. BufferReader 는 오직 String으로만 값을 받지만, 큰 데이터에 있어서는 Scanner보다 효율이 좋다.
  2. 값을 오직 String으로 받기 때문에 String이 아닌 다른값으로 값을 받을 때에는 형변환이 필요하다.
  3. br.readLine()으로 값을 받고, 형변환을 해주어야 한다는 사실만 상기하면 기억하기 쉽다.
  4. public static void main(String args[]) throws IOException BufferedReader 는 예외처리를 꼭 해주어야 한다. try & catch 문을 활용해서 하기도 하지만, 대부분 IOException을 활용해서 한다.

StringTokenizer

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class scratchPad {
    public static void main(String []args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();

        StringTokenizer st = new StringTokenizer(s); //StringTokenizer 인자값에 입력 문자열 넣음
        int a = Integer.parseInt(st.nextToken()); // 첫번째 호출
        int b = Integer.parseInt(st.nextToken()); // 두번째 호출

        System.out.println(a);
        System.out.println(b);
    }
}

BufferedReader로 받은 data는 Line단위로만 나누어 지기 때문에 , 공백 단위로 나누려면 data를 가공해주어야 한다. 이 때 사용하는 것이 StringTokenizer이다.

값을 변환받은 String을 StringTokenizer에 저장해주고, integer값을 받을거면 parseInt에 st.nextToken()값을 넣어준다.

StringTokenizer에 대한 설명은 Parsing 글에서 더 자세히 다루도록 하겠다.

출력에 관해서도 System.out.println("")을 사용하지만, 출력이 많아졌을 때를 고려해서 BufferWriter을 쓰는 것이 좋다.

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 선언
String s = "abcdefg"; // 출력할 문자열
bw.write(s+"\n");// 출력
bw.flush(); // 남아있는 데이터를 모두 출력시킴
bw.close(); // 스트림을 닫음

BufferedWriter 의 경우 Buffer을 잡아놓았기 때문에 반드시 flush()와 close를 통해 뒤처리를 해주어야 한다.

또한 println의 ln 처럼 자동개행이 없기 때문에 개행을 하려면 \n을 통해 해주어야 한다.

정리

↓ 예제코드

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

public class scratchPad {
    public static void main(String []args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 선언

        String s = br.readLine();

        StringTokenizer st = new StringTokenizer(s); //StringTokenizer 인자값에 입력 문자열 넣음
        int a = Integer.parseInt(st.nextToken()); // 첫번째 호출
        int b = Integer.parseInt(st.nextToken()); // 두번째 호출

        bw.write(a+ "\n");
        bw.write(s+ "\n");

        bw.flush(); // 남아있는 데이터를 모두 출력시킴
        bw.close(); // 스트림을 닫음
    }
}

※ 참고

StringBuilder sb = new StringBuilder(br.readLine());

bw.write(String.valueOf(sb));
// bw.write(sb) : 오류 !
bw.flush();
StringBuilder type의 값은 String.valueof() 로 감싸주어야 출력 가능하다
main thorws IOexception
  try(
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in))
        BuffredWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))
     ){
        ...
        bw.write()
        bw.flush()
      }

간단하게 생각해서 위에 처럼 사용한다고 생각하면 편하다.

profile
티스토리로 이사했습니다! https://imsfromseoul.tistory.com/ + https://camel-man-ims.tistory.com/

1개의 댓글

comment-user-thumbnail
2020년 9월 5일

스캐너도 버퍼를 사용하지 않나요?

답글 달기