본문 바로가기
Java & Spring

Java 입출력을 위한 BufferedReader / BufferedWriter

by softserve 2021. 11. 14.
반응형

 

사용자로부터 입력을 받을 수 있는 간편한 방법으로 Scanner 클래스가 있지만 버퍼 용량이 작기 때문에 대량의 데이터를 처리할 때는 속도가 저하되는 문제점이 있습니다.

반면, BufferedReader/Writer 의 경우 버퍼 용량이 커서 대량의 데이터를 입출력할 때 용이하지만 조금 사용하기 까다로운 점이 있습니다. 

입력받기

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

public static void main(String[] args) throws IOException { // 예외처리가 필수

  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

  int n = Integer.parseInt(br.readLine());
  int m = br.read()-48; // 숫자의 ascii 값을 반환하므로
  String s = br.readLine();
}

Scanner가 온갖 자료형으로 입력을 받을 수 있는 것과 달리,

BufferedReader는 기본적으로 String 타입이기 때문에 형 변환을 해주어야 합니다.

BufferedWriter와 달리 명시적으로 close() 를 하지 않아도 garbage collector 에 의해 정리가 되나,

반복적으로 사용할 경우에는 close() 메소드를 통해 닫아줄 필요가 있습니다.

한편, read()는 Scanner의 nextInt() 와 마찬가지로 개행문자를 무시하므로,

위의 예제에서 한 줄씩 입력을 받고자 한다면

br.read(); 이후에 readLine()을 추가하여 개행문자를 제거해줄 필요가 있습니다.

출력하기

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

bw.write("hello buffer\n");

bw.flush(); // 버퍼를 비움
bw.close(); // 닫기

BufferedWriter는 한꺼번에 출력을 하기 때문에

System.out.print 를 반복적으로 사용하는 것보다 시간을 줄일 수 있습니다.

newLine() 메서드로 개행을 할 수 있고,

write() 시 시작지점(offset)과 길이(length)를 지정하여 문자열의 일부분만을 출력할 수도 있습니다.

ex) write(string, offset, length)

 

작동원리

스트림(Stream) 은 강물 따위의 '흐름'을 말합니다.

우리가 입력을 받거나 출력하고자 하는 데이터들 역시 강물처럼 어디선가 흘러왔다가, 다시 목적지를 향해 흘러가는 특성을 가지고 있고 그래서 우리는 이것을 스트림이라고 부릅니다.

InputStreamReader 객체는 키보드를 통해 입력된 System.in의 바이트 단위의 스트림을 문자 단위 스트림으로 바꿔 BufferedReader에게 전달합니다.

BufferedReader 객체는 사용자가 read()나 readLine() 등의 메서드로 데이터 요청을 보내면 가지고 있던 스트림을 적당히 잘라 넘겨줍니다.

반대로 OutputStreamWriter 객체는 출력하고자 하는 문자를 바이트 스트림으로 바꿔 BufferedWriter에게 전달합니다.

BufferedWriter 객체는 write() 메서드가 호출될 때마다 버퍼에다가 그 내용을 기록하고

flush() 메서드가 호출되면 그것들을 한번에 쏟아냅니다.

반응형

댓글