Java에서 BufferedReader와 BufferWriter 사용하기
BufferedReader와 BufferedWriter은 이름처럼 버퍼를 이용해서 읽고 쓰는 함수입니다.
이 함수는 버퍼를 이용하기 때문에 이 함수를 이용하면 입출력의 효율이 비교할 수 없을 정도로 좋아집니다.
한 번 거쳐가므로 느릴거 같은데 왜 빠를까요?
하드디스크는 원래 속도가 매우 느립니다.
하드디스크 뿐만 아니라 키보드나 모니터와 같은 외부 장치와의 데이터 입출력은 생각보다 시간이 걸리는 작업입니다.
버퍼링 없이 키보드가 눌릴 때마다 눌린 문자의 정보를 목적지로 바로 이동시키는 것이 보다 효율적이고 빠릅니다.
그냥 전송하게 되면 CPU의 성능 갭이 많이 나서 비효율적입니다.
예를 들자면, 흙을 퍼서 저 언덕에 버리는데, 한 번 삽질할 때마다 가서 버리는 것보다, 수레에 가득 채워서 한 번에 나르는 것이 효율적인것과 같은 것 입니다.
즉 모아뒀다가 한 번에 전송하는 것이 훨씬 효율적이라는 것입니다.
1 | # 버퍼 입출력 |
BufferedReader
자바를 사용하는 사람들은 보통 Scanner를 이용해 입력받아 사용하는데, 띄어쓰기(스페이스)와 엔터(개행문자)를 경계로 입력값을 인식하기 때문에 따로 가공할 필요가 없어서 사용하기 매우 편리합니다.
반면에 BufferedReader는 엔터만 경계로 인식하고 받은 데이터가 String으로 고정되기 때문에 데이터를 따로 가공해야 하는 경우가 많습니다.
그래소 다소 번거롭습니다. 하지만 Scanner에 비해서 상대적으로 빠릅니다.
공식 문서에는
Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines. The buffer size may be specified, or the default size may be used.
입력 스트림에서 문자를 읽는 함수인데 문자나 배열, 라인들을 효율적으로 읽기 위해서 문자들을 버퍼에 저장하고(버퍼링) 읽는 방법을 취합니다. 버퍼 사이즈는 우리가 지정할 수도 있지만 지정안할 경우에는 기존 디폴트 사이즈가 적용됩니다.
따라서 알고리즘 풀 때 BufferedReader를 이용한 해설을 많이 볼 수 있습니다. 많은 데이터를 입력받아야 할 상황에서는 BufferedReader를 이용해줍시다.
BufferedReader 사용방법
BufferedReader의 readLine()을 사용하면 데이터를 라인 단위로 읽을 수 있습니다.
readLine 함수의 리턴 값은 String으로 고정되기 때문에 String이 아닌 다른 타입으로 입력을 받으려면 형변환을 꼭 해줘야 합니다.
1 | import java.io.*; |
위처럼 한 줄 한 줄 읽습니다. 그런데 공백단위로 데이터를 알려면 어떻게 해야할까요?
Scanner는 공백단위로도 끊어주기 때문에 이런걸 고려할 필요가 없었습니다.
StringTokenizer의 nextToken함수를 이용하거나 String클래스의 slplit함수를 이용해야 합니다.
BufferedReader클래스의 또 다른 메인 함수들
Modifier and Type | Method and Description |
---|---|
void | Close() 입력 스트림을 닫고 사용하던 자원들을 풉니다. |
void | mark(int, readAheadLimit) 스트림의 현재 위치를 마킹합니다. |
boolean | markSupported() 스트림이 mark 기능을 지원하는지 true/false로 알려줍니다. |
int | read() 한 글자만 읽어 정수형으로 반환해줍니다. 즉 3을 ‘3’이라고 읽어서 ‘3’의 정수형인 (int)’3’ = 51을 반환 3을 친다고 해서 3을 리턴해주는 메소드가 아니다. |
int | read(char[] cbuf, int offset, int length) cbuf의 offset 위치부터 length 길이만큼 문자를 스트림으로부터 읽어옵니다. |
String | readLine() 한줄을 읽는다. String으로 변환 |
boolean | ready() 입력스트림이 사용될 준비가 되어있는지 확인해줌. 1이면 준비완료 |
void | reset() 마킹이 있으면 그 위치부터 다시 시작, 그렇지 않으면 처음부터 다시 시작. |
long | skip(long n) n개의 문자를 건나뜀. |
BufferedWriter
마찬가지로 System.out.print(“”); 과 동일하게 사용가능한 함수입니다.
BufferedWriter 함수 또한 버퍼를 이용하기 때문에 성능면에서 더 좋다.
많은 양의 출력이 필요할 때에는 마찬가지로 이것을 이용해주는 것이 좋다.
System.out.println처럼 함수가 문자열 출력과 개행을 동시에 해주지 않기 때문에 개행을 하려면 write에 “\n”를 넣어주거나 newLine함수를 사용해야합니다.
1 | import java.io.*; |
버퍼를 이용하는 것이기 때문에 다 쓴 뒤에는 버퍼를 클린하게 해주어야 합니다.
flush() 함수를 통해 버퍼에 남아있는 데이터를 출력해 없앤 후, 스트림을 닫아줍니다.
BufferedWriter 클래스의 또 다른 메인 함수들
Modifier and Type | Method and Description |
---|---|
void | Close() 스트림을 닫습니다. 닫기 전에 flushing 해줍니다. |
void | flush() 스트림을 비웁니다. |
void | newLine() 개행역할을 합니다. |
void | write(char[] cbuf, int offset, int length) 버퍼 offset위치부터 length 크기만큼 write 합니다. |
void | write(int c) 한 글자 쓰기 |
void | write(String s, int offset, int length) 문자열에서 offset부터 일정 길이만큼 write 해주기. |
예제 - 백준 15552번
1 | package For.P15552; |
위 문제의 경우 Scanner로 풀면 정말 간단하지만, 테스트 케이스가 많아진다면 Scanner보단 Buffer을 사용하는것이 효율적이다.
#Printwriter #FileWriter #OutputStreamWriter #StringTokenizer #String
References
Java에서 BufferedReader와 BufferWriter 사용하기
install_url
to use ShareThis. Please set it in _config.yml
.