BufferedReader와 BufferdWriter는 버퍼를 사용하여 읽기와 쓰기를 하는 함수이다.
- 버퍼를 사용하지 않는 입력은, 키보드의 입력이 키를 누르는 즉시 바로 프로그램에 전달
- 반면! 버퍼를 사용하는 입력은, 키보드의 입력이 있을 때마다 한 문자씩 버퍼로 전송된다.
- 버퍼가 가득차거나 개행 문자가 나타나면 버퍼의 내용을 한 번에 프로그램에 전달한다.
+ 버퍼 : 일시적으로 데이터를 보관하는 임시 메모리 영역
스캐너보다 버퍼리더의 버퍼 사이즈가 압도적으로 크기 때문에 입력이 많을 때 버퍼리더가 훨씬 유리하다!
Q. 근데 버퍼를 거치는 것보다, 입력을 받는 즉시 출력하는게 더 빠른거 아닐까?
A. 생각보다 외부장치 (키보드, 모니터 등)는 데이터 입출력하는데 시간이 오래 걸린다. 그래서 바로 이동시키는 것 보다는 중간에 버퍼를 두어 한 번에 묶어 보내는 것이 더 효율적이고 빠른 방법이다.
+ 비유 쓰레기가 생길 때마다 하나하나 바로 버리는 것 보다, 쓰레기통에 하나하나 모았다가 꽉 차면 한 번에 버리는 것이 훨씬 효율적!
우선 수업에서도 그렇고 입출력을 다룰 때 보통 가장 먼저 배우게 되는 스캐너는 띄어쓰기와 개행문자를 경계로 하여 입력 값을 인식한다. 즉! 따로 가공할 필요가 없어 편리하다.
가공할 필요가 없다는 뜻은 int형 변수를 입력 받고자 할 때 scanner.nextInt()를 사용하면 바로 원하는 타입의 입력을 받을 수 있다. 하지만 BufferedReader는 입력 받은 데이터가 String으로 고정되기 때문에 입력받은 데이터를 원하는 타입으로 가공하는 작업이 필요하다.
- BufferedReader 사용법
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언
String s = br.readLine();
int i = Integer.parseInt(br.readLine());
입력은 readLine() 이라는 메소드를 사용한다. (스캐너에서 nextLine()의 역할과 같음)
String으로 리턴값이 고정되어 있기 때문에, 다른 타입으로 입력을 받고자 하면 형변환을 해주어야 한다.
그리고 예외처리를 반드시 필요로 하기 때문에 try/catch문으로 감싸주거나, throws IOException을 통해 예외처리를 한다. (주로 후자를 사용)
- 공백 단위로 데이터를 가공하고자 할 때
// StringTokenizer
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
// String.split() 함수
String arr[] = s.split(" ");
StringTokenizer
- nextToken() 함수를 쓰면 readLine()을 통해 입력 받은 값을 공백 단위로 구분하여 순서대로 호출할 수 있다.
- 만약 입력이 “50 39” 이면 N은 50 M은 39
- 구분자를 지정해줄 수도 있음 (지정하지 않으면 공백 기준으로 구분)
Split
- 배열에 공백 단위로 끊어 데이터를 저장하여 사용할 수 있다.
- BufferedWriter 사용법
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String s = "abcdefg"; //출력할 문자열
bw.write(s); //출력
bw.newLine(); //줄바꿈 문자열 출력
bw.write(s+"\\n");
bw.flush(); //남아있는 데이터를 모두 출력시킴
bw.close(); //스트림을 닫음
write()를 사용하여 출력할 내용을 담고, flush()를 통해서 버퍼를 비워낸다.
- 주의할 점
- write()만 사용한다고 콘솔에 출력되는 건 아니고 반드시 flush()를 써줘야한다.
- 버퍼를 잡아 놓았기 때문에 BufferedWriter 사용시 flush()/ close()를 반드시 호출해 주어야한다.
- 그리고 bw.write() 에는 System.out.println();과 같이 자동개행 기능이 없기 때문에 개행을 해줘야할 경우에는 bw.newLine()이나 \\n를 통해 따로 처리해줘야 한다.
- BufferedWriter을 사용시 정수를 그대로 출력하려고 할 경우에 제대로 출력되지 않는다. 따라서 BufferedWriter에 넣을 때, String형으로 변환이 필요하다.또는 + “ “ ⇒ 문자열로 인식
- 또는 +”” ⇒ 문자열로 인식
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int[] array = {1,2,3,4,5,6,7,8,9};
bw.write("int형 String으로 변환 출력: ");
for(int i=0; i<9; i++) { // int형을 String으로 바꿔 출력할 경우
bw.write(String.valueOf(array[i]));
bw.write(" ");
}
bw.flush();
또는
br.write(array[i]+"");
또는
br.write(array[i]+" ");
+ 백준 15552번 : 빠른 A+B
+ 출력 속도 비교
+ StringTokenizer
+ 질문
- 왜 정수 출력 X?
⇒ String 기반이라서 - 왜 flush() 안 했는데 출력됨?
⇒ 버퍼가 가득차거나, close()가 선언되면 flush()를 쓰지 않아도 출력된다!
'스터디 > 성희' 카테고리의 다른 글
Servlet Filter, Spring Interceptor 차이 (0) | 2024.04.24 |
---|---|
IoC 컨테이너의 개념 및 역할 (0) | 2024.04.24 |