본문 바로가기

스터디/성희

BufferedReader, BufferedWriter

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

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

+ 버퍼 : 일시적으로 데이터를 보관하는 임시 메모리 영역

 

스캐너보다 버퍼리더의 버퍼 사이즈가 압도적으로 크기 때문에 입력이 많을 때 버퍼리더가 훨씬 유리하다!

 

Q. 근데 버퍼를 거치는 것보다, 입력을 받는 즉시 출력하는게 더 빠른거 아닐까?

A. 생각보다 외부장치 (키보드, 모니터 등)는 데이터 입출력하는데 시간이 오래 걸린다. 그래서 바로 이동시키는 것 보다는 중간에 버퍼를 두어 한 번에 묶어 보내는 것이 더 효율적이고 빠른 방법이다.

+ 비유 쓰레기가 생길 때마다 하나하나 바로 버리는 것 보다, 쓰레기통에 하나하나 모았다가 꽉 차면 한 번에 버리는 것이 훨씬 효율적! 

 

우선 수업에서도 그렇고 입출력을 다룰 때 보통 가장 먼저 배우게 되는 스캐너는 띄어쓰기개행문자를 경계로 하여 입력 값을 인식한다. 즉! 따로 가공할 필요가 없어 편리하다.

가공할 필요가 없다는 뜻은 int형 변수를 입력 받고자 할 때 scanner.nextInt()를 사용하면 바로 원하는 타입의 입력을 받을 수 있다. 하지만 BufferedReader는 입력 받은 데이터가 String으로 고정되기 때문에 입력받은 데이터를 원하는 타입으로 가공하는 작업이 필요하다.

 

  • BufferedReader 사용법
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언

String s = br.readLine();

int i = Integer.parseInt(br.readLine());

입력은 readLine() 이라는 메소드를 사용한다. (스캐너에서 nextLine()의 역할과 같음)

String으로 리턴값이 고정되어 있기 때문에, 다른 타입으로 입력을 받고자 하면 형변환을 해주어야 한다.

그리고 예외처리를 반드시 필요로 하기 때문에 try/catch문으로 감싸주거나, throws IOException을 통해 예외처리를 한다. (주로 후자를 사용)

 

  • 공백 단위로 데이터를 가공하고자 할 때
// StringTokenizer 
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

String s = br.readLine();

StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());

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

 

StringTokenizer

  • nextToken() 함수를 쓰면 readLine()을 통해 입력 받은 값을 공백 단위로 구분하여 순서대로 호출할 수 있다.
  • 만약 입력이 “50 39” 이면 N은 50 M은 39
  • 구분자를 지정해줄 수도 있음 (지정하지 않으면 공백 기준으로 구분)

Split

  • 배열에 공백 단위로 끊어 데이터를 저장하여 사용할 수 있다.

  • BufferedWriter 사용법
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); 

String s = "abcdefg";   //출력할 문자열
bw.write(s); //출력
bw.newLine(); //줄바꿈 문자열 출력
bw.write(s+"\\n");  

bw.flush();   //남아있는 데이터를 모두 출력시킴

bw.close();   //스트림을 닫음

write()를 사용하여 출력할 내용을 담고, flush()를 통해서 버퍼를 비워낸다.

  • 주의할 점
  1. write()만 사용한다고 콘솔에 출력되는 건 아니고 반드시 flush()를 써줘야한다.
  2. 버퍼를 잡아 놓았기 때문에 BufferedWriter 사용시 flush()/ close()를 반드시 호출해 주어야한다.
  3. 그리고 bw.write() 에는 System.out.println();과 같이 자동개행 기능이 없기 때문에 개행을 해줘야할 경우에는 bw.newLine()이나 \\n를 통해 따로 처리해줘야 한다.
  4. BufferedWriter을 사용시 정수를 그대로 출력하려고 할 경우에 제대로 출력되지 않는다. 따라서 BufferedWriter에 넣을 때, String형으로 변환이 필요하다.또는 + “ “ ⇒ 문자열로 인식
  5. 또는 +”” ⇒ 문자열로 인식
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        int[] array = {1,2,3,4,5,6,7,8,9};

        bw.write("int형 String으로 변환 출력: ");
        for(int i=0; i<9; i++) { // int형을 String으로 바꿔 출력할 경우
            bw.write(String.valueOf(array[i]));
            bw.write(" ");
        }
        bw.flush();
        
        
또는 
				br.write(array[i]+"");
또는 
				br.write(array[i]+" ");

 

 

+ 백준 15552번 : 빠른 A+B

+ 출력 속도 비교

+ StringTokenizer

 

+ 질문

  • 왜 정수 출력 X?
    ⇒ String 기반이라서
  • 왜 flush() 안 했는데 출력됨?
    ⇒ 버퍼가 가득차거나, close()가 선언되면 flush()를 쓰지 않아도 출력된다!

'스터디 > 성희' 카테고리의 다른 글

Servlet Filter, Spring Interceptor 차이  (0) 2024.04.24
IoC 컨테이너의 개념 및 역할  (0) 2024.04.24