백준과 같이 input 값을 직접 받아야 하는 알고리즘 문제를 자바로 풀다 보면 Scanner 사용 시 시간 초과가 발생하는 문제가 있다.
이를 BufferedReader와 BufferedWriter를 사용해 해결한다.
#BufferedReader
문자열을 입력받는 Scanner에 대응되는 클래스이다.
다만, 잘 알고쓰자.
먼저 Oracle 공식 문서를 보면,
Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.
요약하면 BufferedReader는 문자를 버퍼링 하는 클래스이다.
원래 InputStreamReader라는 문자열 입력 클래스가 존재했었는데, 문자열을 Character 단위로 한 글자씩 읽어 들이다 보니 불편하고 비효율적이었고, 이를 보완하고자 버퍼링 기능을 추가한 BufferedReader가 존재하게 된 것이다.
이 BufferedReader는 사용자가 요청할 때마다 데이터를 읽어오지 않고 우선 버퍼에 보관한 뒤 요청이 들어오면 버퍼에서 꺼내오는 식으로 동작한다.
또한, 라인 단위로 입력을 받기에 whitespace도 String으로 인식하며, 데이터 타입이 String으로 fix 되어 있어 이후에 형 변환을 따로 해주어야만 한다.
(문자열 파싱 없이 읽어 들이기에 Scanner에 비해 속도가 빠른 것이다.)
클래스 내부를 살펴보면 버퍼의 크기도 BufferedReader 클래스가 Scanner 클래스보다 무려 8배 크다.
* BufferedReader 클래스의 버퍼 사이즈
* Scanner 클래스의 버퍼 사이즈
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
String inputText = br.readLine(); // 문자열 입력받기
int inputInteger = Integer.parseInt(br.readLine()); // 문자열로 받아 정수로 변환
System.out.println(inputText);
System.out.println(inputInteger);
br.close();
}
}
주의해야 할 점은 Scanner 클래스와 달리 IOException을 던지기 때문에 try catch로 감싸던 throws를 하던 예외처리를 해주어야 한다.
그리고 사용이 끝났으면 스트림을 닫아주자! (GC가 해주겠지라는 안일한 생각으로 코딩하지 말자..)
#BufferedWriter
문자열을 출력하는 System.out.println()에 대응된다.
BufferedWriter의 경우 BufferedReader와 반대로 버퍼에 데이터를 모아놨다가 한 번에 출력하기에 System.out.println()에 비해 속도가 빠르다.
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
public class Main {
private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
private static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException {
String inputText = br.readLine(); // 문자열 입력받기
int inputInteger = Integer.parseInt(br.readLine()); // 문자열로 받아 정수로 변환
// 버퍼에 쓰기
bw.write(inputText + "\n"); // 개행 문자로 개행
bw.write(String.valueOf(inputInteger));
// newLine 메서드로 개행
bw.newLine();
br.close();
// 버퍼에 있는 데이터 출력 스트림에 반영
bw.flush();
/*
츨력 결과
asdf
1
*/
bw.close();
}
}
주의해야 할 점은 BufferedReader와 마찬가지로 예외처리를 해주어야 하며 자동으로 개행을 해주지 않기에 개행 문자를 직접 추가하거나 newLine 메서드를 호출하여 개행을 해줘야 한다.
또한, write는 실제 출력이 아닌 버퍼에 쓰는 것일 뿐이므로 반드시 flush를 해주어야 출력 스트림에 반영된다.
마지막으로 사용이 끝났으면 스트림을 닫아주자! (GC가 해주겠지라는 안일한 생각으로 코딩하지 말자!)
'Language & Runtime > Java' 카테고리의 다른 글
[Java] Stream API (0) | 2022.12.30 |
---|