본문 바로가기

JAVA

자바 bufferedreader & writer 사용법과 IOException (백준 15552번)

Scanner를 사용할 때는 java.util 패키지를 임포트하지만, BufferedReader/Writer는 java.io 패키지를 임포트해야한다. 이 패키지 안에는 I/O(입출력)와 관련된 여러 클래스들이 존재하는데, 그 중 버퍼를 활용하여 입출력을 수행하는 클래스가 BufferedReader/Writer이다.

import java.io.*;

 

Scanner는 1024 char 만큼의 버퍼를 가지지만, Buffered-는 그 8배의 버퍼를 가진다. 따라서 많은 양의 입출력을 수행할 때는 Buffered- 클래스를 활용하는 것이 더 빠르게 처리할 수 있다. 

 

먼저 입력값을 받을 BufferedReader 객체와, 출력값을 저장할 BufferedWriter 객체를 생성해주어야 한다. 이 때 파라미터로 Reader/Writer 클래스의 객체와 버퍼의 사이즈를 전달할 수 있는데, 보통 버퍼 사이즈는 생략하고 쓴다. 나는 System.in으로 입력값이 주어지는 경우 string 형태로 읽고 쓰는 InputStreamReader와 OutputStreamWriter를 쓰고 있다. 아래와 같이 객체를 생성하면 된다.

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

 

이제 객체를 생성했으므로 BufferedReader와 BufferedWriter의 여러 메소드들을 활용해 입력값을 읽고 원하는 값을 출력할 수 있다. 사용되는 대표적인 메소드는 다음과 같다.

클래스

메소드

리턴타입

작동방식

BufferedReader

read()

int

문자 하나를 읽어 int형으로 리턴. 

readLine()

String

한 줄의 문자열을 읽음

skip(n)

long

n개의 문자를 스킵하고 넘어간다.

BufferedWriter

write(s)

-

문자 또는 문자열 s를 출력한다.

newLine()

-

빈 줄을 작성한다.

flush()

-

남은 값들을 모두 출력시킨다.

close()

-

스트림을 종료한다.

 

읽어올 때는 대부분 readLine()을 사용한다. 앞서 생성한 객체를 이용해 readLine() 메소드에 접근해 String 변수에 저장하면 된다.

String s = br.readLine();

 

쓸 때는 주로 write()을 이용하는데, 줄바꿈이 포함되어있지 않으므로, 한 줄을 내리고 싶다면 newLine()을 호출해야 한다.

bw.write(s);
bw.newLine(); // 개행하고 싶은 경우

 

 

주의할 점

1) BufferedReader의 read()와 readLine()은 리턴타입이 다르기 때문에 구분해서 사용해야 한다. read()는 문자를 읽어 그에 해당하는 ASCII 10진수 정수를 반환하기 때문에, 숫자를 바로 입력받을 수 있다고 생각하면 안된다. 예를 들어 첫 문자가 0-9까지의 숫자라면 그에 상응하는 ASCII 10진수 int값인 48-57이 반환된다.

2) 숫자를 입력받고 싶다면, readLine()으로 string으로 읽어온 후 parseInt() 메소드를 이용해 int형으로 변환할 수 있다. 만약 readLine을 사용하여 읽어온 줄에 공백이 있어 분리하고 싶다면 indexOf로 공백의 위치를 알아내 substring을 이용해 공백 전, 후로 분리한다 (아래 예제 코드 참고). 만약 공백이 여러 개라면 split을 이용해 배열로 저장해 사용할 수도 있다.

3) BufferedWriter의 write 메소드는 문자열만 작성할 수 있으므로, 숫자를 작성하고 싶다면 toString 메소드를 이용해 먼저 문자로 변환해야 한다.

4) BufferedWriter 객체는 반드시 flush() 또는 close()를 해서 스트림을 끝내야 한다. 

5) BufferedReader와 BufferedWriter 클래스의 메소드들은 입출력에러가 발생할 경우 자체적으로 IOException을 던지도록 정의되어있다. 그러므로 이 메소드들을 사용할 때 반드시 예외처리를 해주어야 한다. 아래 예제처럼 메인함수를 작성할 때 throws IOException으로 처리해주면 편리하다.

 

 

<백준 15552번 정답코드>

import java.io.*;

class Main{
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		int num = Integer.parseInt(br.readLine());
        
        while(num>0){
            num--;
            
            String line = br.readLine();
            int pos = line.indexOf(" ");
            int a = Integer.parseInt(line.substring(0,pos));
            int b = Integer.parseInt(line.substring(pos+1));
            int result = a+b;
            
            bw.write(Integer.toString(result));
            bw.newLine();
        }
        
        bw.close();
    }
}