[Java] 빠른 입출력을 위한 BufferedReader, BufferedWriter 함수

enjoy89·2022년 6월 16일
2
post-thumbnail

BufferedReader, BufferedWriter

  • 단어 그대로 버퍼를 이용한 입출력 I/O(Input/Output) 함수이다.
  • 사용자로부터 키보드로 데이터를 입력 받을 때, 키보드를 누르는 순간 입력 데이터를 전달하는 것이 아니고 버퍼에 잠시 저장해두었다가 전달하는 방법으로 동작한다.
  • 이와 같이 버퍼를 이용하면 입출력의 속도가 매우 빨라지는데, 그 이유는 무엇일까?

🍎 예를 들어 1000개의 사과를 A에서 B로 옮긴다고 상상해보자.

  • 사과를 이동시키는 방법은 2가지가 존재한다.

  • 첫 번째는 사과를 양 손에 2개씩 들고 A에서 B로 500번 이동하는 것이고,

  • 두 번째는 사과를 바구니에 50개씩 담아 20번 이동하는 것이다.

  • 당연히 바구니를 사용하여 사과를 옮기는 것이 시간과 체력 모두 세이브되는 방법이다. 이때 사용한 바구니가 바로 버퍼이다.

  • 즉, 버퍼를 이용한 입출력은 바로 하나씩 데이터를 전달하지 않고 버퍼에 모아두고 한 번에 전달하는 방식이기 때문에 속도가 빠르고 효율적이다.

  • 컴퓨터구조 측면에서 입출력에 대한 이야기

    • 사용자로부터 키보드와 모니터 등의 외부 장치를 통한 입출력은 생각보다 시간이 오래 걸리는 작업에 속한다.
    • 내부 버스로 연결되어 있어 처리 속도가 매우 빠른 CPU에 비해 기억 장치인 무거운 하드디스크의 경우는 속도가 매우 느리기 때문에 장치 사이에 속도 차이가 나게 되어 있다. 바로 이러한 문제가 발생하기 때문에 버퍼를 이용하는 것이다.
    • 버퍼를 이용하면 두 장치의 속도 차이는 줄고 시스템의 효율은 높아진다.

Scanner vs BufferedReader

  • 또다른 입출력 함수인 Scanner와 비교해보자.
    • 먼저 Scanner 함수는 Space(공백), Enter(개행문자)의 경계값을 기준으로 입력 데이터를 인식하고, BufferedReader 함수는 Enter(개행문자)만을 기준으로 입력 데이터를 인식한다.
    • 즉, 하나하나 즉시 전달하지 않고 모든 데이터를 버퍼에 모아두었다가 한 번에 전달하는 방식이다.
    • 이와 같은 이유로 두 함수의 속도 차이가 나는 것이다. 물론 입력 데이터의 양이 적을 경우에는 차이가 미미하겠지만 데이터의 양이 커질 경우 속도 차이가 매우 많이 난다.
    • 하지만 이러한 부분에서 Scanner 함수를 이용해 입력받은 데이터는 따로 가공이 필요하지 않기 때문에 편리하게 사용할 수 있지만 BufferedReader 함수를 이용하여 입력받은 데이터는 따로 상황에 따라 가공이 필요할 수 있고 데이터 형식이 String으로 고정되어 있기 때문에 사용이 조금 번거로울 수는 있다.

BufferedReader 사용법

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // Case1 -> String type data
        String data_string = br.readLine();

        // Case2 -> Integer type data
        int data_int = Integer.parseInt(br.readLine());
    }
}
  • BufferedReader의 readLine()을 이용하여 데이터를 한 라인 단위로 읽을 수 있다. readLine()의 return 타입이 String으로 고정되어 있기 때문에 다른 타입인 경우 형변환이 필수이다.

BufferedWriter 사용법

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        String str = "Hello Java";
        bw.write(str);

        br.close();
        bw.flush(); // 남은 데이터 모두 출력
        bw.close();
  • 버퍼를 모두 사용하고 난 후에 버퍼를 비우는 마무리 작업이 필요하다. flush() 함수를 이용하여 남은 데이터를 모두 출력하고 close() 함수를 이용하여 스트림을 닫아주어야 한다.
profile
Backend Developer 💻 😺

0개의 댓글