알고리즘

BufferedReader

대추언니 2020. 1. 26. 19:37

BufferReader

BufferedReader/BufferedWriter는 Buffer에 있는 IO 클래스이다.

버퍼를 이용해서 읽고 쓰는 함수로 입(출)력된 데이터가 바로 전달되지 않고 버퍼링 된 후에 전달되기 때문에 시스템의 데이터 처리 효율성을 높여준다.

버퍼스트림을 InputStreamReader, OutputStreamWriter를 같이 사용하여 버퍼링을 하게되면 입출력 스트림으로부터 미리 버퍼에 데이터를 가져다 놓기 때문에 보다 효율적인 입출력이 가능해진다.

버퍼를 사용한 입출력

하드디스크는 원래 속도가 느릴 뿐만 아니라 키보드, 모니터같은 외부 장치와의 데이터 입출력은 시간이 오래걸리는 작업이다.
버퍼링없이 키보드가 눌릴 때마다 문자를 바로 전송하는 것 보다 중간에 메모리 버퍼를 둬서 데이터를 한데 묶어서 이동시키는 것이 보다 효율적이고 빠르다.

Buffer : 데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 일시적으로 데이터를 보관하는 임시 메모리 영역

우리가 처음 Java를 배웠을 때는 Scanner를 이용해 입력 받는 것을 배운다. 물론 나도 그렇게 배웠기 때문에 여태까지 알고리즘 풀이에 있어 처음에는 Scanner를 사용했다.
Scanner는 띄어쓰기, 엔터를 경계 값으로 인식하기 때문에 따로 가공할 필요가 없어 사용하기 매우 편리했다.

하지만 BufferedRedader는 엔터만 경계로 인식하고 받은 데이터가 String으로 고정되기 때문에 데이터를 따로 가공해야한다. 물론 버퍼를 사용하기 때문에 BufferedReader가 상대적으로 빠르다.

공식 문서에는 입력 스트림에서 문자를 읽는 함수인데 문자나 배열, 라인들을 효율적으로 읽기 위해 문자들을 버퍼에 저장하고 읽는 방식(버퍼링)을 취한다고 한다.

이와 같이 알고리즘을 풀 때 BufferedReader를 사용하는 것이 보다 많은 데이터를 입력받을 때 효율적으로 풀이할 수 있는 방법이다.

BufferedReader 사용하기

BufferedReader의 readLine 메서드를 사용하면 데이터를 줄 단위로 읽을 수 있다.

1
2
3
4
5
6
7
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(bf.readLine());
 
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());

readLine를 호출할 때는 리턴 값이 String이기 때문에 String이 아닌 다른 타입으로 입력을 받으려면 형변환을 꼭 해주어야 한다. 또한 예외처리를 꼭 해주어야하는데 보통 try-catch보다는 throws IOExceptions을 사용한다.

readLine을 통해 읽어들인 데이터는 Line 단위로만 나눠지기 때문에 공백 단위로 데이터를 가공하기 위해 StringTokenizer의 nextToken함수를 하용했다. 이는 입력받은 값을 공백단위로 구분하여 순서대로 호출할 수 있다. 이 외에도 String의 split함수를 활용하여 배열에 넣은 데이터를 사용할 수 있다.

BufferedWriter

보통 우리는 출력할 때 System.out.println()을 사용한다. 이도 마찬가지로 데이터 양이 적을 경우 성능차이가 미미하겠지만 많은 양의 데이터를 출력해야한다면 Buffer를 활용하는 것이 좋다.

1
2
3
4
5
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
bw.write("abcdefg\n");
bw.flush(); // 남아있는 데이터를 모두 출력시킴
bw.close(); // 스트림 close

BufferedWriter의 경우 flush(), close()를 호출해서 버퍼를 클린하게 해주어야 한다. 또한 bw.write()에는 개행기능이 없기 때문에 개행을 해주어야할때는 \n을 덧붙이거나 bw.newLine()을 통해 개행을 해줄 수 있다.

주요 메소드

메서드명 기능
BufferedReader(Reader rd) rd에 연결되는 문자입력 버퍼 스트림 생성
BufferedWriter(Writer wt) wt에 연결되는 문자출력 버퍼 스트림 생성
int read() 스트림으로부터 한 문자를 읽어서 int형으로 리턴
int read(char[] buf) 문자배열 buf의 크기만큼 문자를 읽어들임. 읽어들인 문자 수를 리턴
int read(char[] buf, int offset, int length) buf의 offset 위치부터 length 길이만큼 문자를 스트림으로부터 읽어들임
String readLine() 스트림으로부터 함수를 읽어 문자열로 리턴
void mark() 현재 위치를 마킹. 차후 reset()을 이용하여 마킹위치부터 시작
void reset() 마킹이 있으면 그 위치부터 다시 시작. 그렇지 않으면 처음부터 다시 시작
long skip(int n) n개의 문자를 건너 뜀
void close() 스트림 닫음
void write(int c) int형으로 문자 데이터를 출력 문자스트림으로 출력
void write(String s, int offset, int length) 문자열 s를 offset위치부터 length 길이만큼 출력스트림으로 출력
void write(char[] buf, int offset, int length) 문자배열 buf의 offset위치부터 length 길이만큼을 출력스트림으로 출력
void newLine() 줄바꿈 문자열 출력
void flush 남아있는 데이터를 모두 출력시킴

 

 

참고 블로그
https://coding-factory.tistory.com/251
https://jhnyang.tistory.com/92