본문 바로가기
JAVA

[JAVA] Scanner와 BufferedReader/BufferedWriter

by snow_white 2022. 1. 19.

보통 JAVA 언어를 처음 접하면 System.out.println(); 으로 문장을 출력하는 것부터 배우게 된다. 이때, 문자는 키보드로 입력을 받아야하기 때문에 Scanner 클래스를 사용할 것이다.

// Scanner 클래스 사용하여 입출력
import java.util.Scanner;
import java.io.InputStream;

public class test01 {
	public static void main(String[] args) {
		// 알고리즘 문제 풀 때 모든 입력이 정수이고 띄어쓰기로 구분되는 경우 스캐너 편함.
		InputStream in = System.in; // 키보드로 입력한 데이터를 읽기 위해 표준 입력 스트림을 얻음
        	Scanner sc = new Scanner(in); // 사용자의 키보드 입력을 처리하기 위해 Scanner 객체를 생성함
		int num = sc.nextInt(); // 키보드로 입력한 데이터를 읽어서 변수에 저장
        	sc.close(); // 읽기 작업이 종료되어 Scanner 객체 닫음
		System.out.println("num1 : "+num1); // 표준 출력
	}
}

 

하지만

코딩테스트라는 걸 준비하기 시작하면서 소스 코드의 효율, 메모리 사용량 등 고려해야 할 사항들이 꽤 많다는 사실을 깨달았다. 효율을 위해서 Scanner로 입력 받기보다 BufferedReader 클래스를 사용한다.

Scanner를 통해 입력을 받으면 Spacebar, Enter를 경계로 데이터가 String값으로 고정된다. 따라서 문자열을 가공하는 데에 작업이 필수적이다.

버퍼링 기능을 추가하게 되면 입출력 스트림으로부터 미리 버퍼에 데이터를 갖다 놓기 때문에 보다 효율적으로 입출력이 가능하다.

 

또한, System.out.println(); 은 BufferedWriter의 write();로 대체하여 메모리 공간을 절약한다.

// BufferedReader 사용하여 입출력
// 버퍼드 리더는 스캐너보다 코딩이 불편하지만
// 스캐너 버그 해결 + 속도 및 메모리 성능이 스캐너보다 우수.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InptStream;
import java.io.OutputStreamWriter;

public class test02 {
	public static void main(String[] args) throws NumberFormatException, IOException {
		/*
        	InputStream in = System.in;	// 키보드로 입력한 데이터를 읽기 위해 표준 입력 스트림을 얻음.
		InputStreamReader reader = new InputStreamReader(in); // InputStream 객체를 인자로 하여 InputStreamReader 객체를 생성함
		BufferedReader buffReader = new BufferedReader(reader);	// InputStreamReader 객체를 인자로 하여 BufferedReader 객체를 생성함
        	*/
       		// 한줄 표현
        
       		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        	BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        
       		//String s = br.readLine(); // 문자열 저장
		int num1 = Integer.parseInt(br.readLine()); // String을 int형으로 변환
		bw.write("num1 : "+String.valueOf(num1));
		bw.flush(); // write로 담은 내용 출력 후, 버퍼를 비움.
		bw.close(); 
		
	}
}

Scanner 클래스

 Scanner 클래스는 io 패키지에서 제공하는 클래스는 아니지만 표준 입력 스트림으로부터 데이터를 읽어 들일 수 있는 클래스임

 Scanner 클래스를 이용하면 키보드 입력 같은 표준 입력 작업을 단순하게 처리할 수 있음

 

<Scanner의 생성자>

Scanner의 생성자
설명
Scanner (InputStream in)
지정된 입력 스트림에서 스캔한 값을 생성
Scanner (InputStream in, String charsetName)
지정된 입력 스트림에서 스캔한 값을 생성

<Scanner의 주요 메서드>

Scanner의 메서드
설명
String next() 스캐너에서 다음 토큰을 찾아 반환, 개행 문자를 기준으로 입력 종료
int nextInt() 입력 받은 다음 토큰을 int형으로 반환, 정수형 문자 한 개 입력 받고 종료
String nextLine() 현재 줄을 지나서 진행하고 건너뛴 입력을 반환, 개행 문자를 기준으로 입력 종료

BufferdReader / BufferedWriter

 BufferedInputStream 및 BufferedOutputStream과 동일하게 입출력 스트림에 버퍼 기능을 추가한 문자 스트림임

 문자 입력 스트림으로부터 문자를 읽어 들이거나 문자 출력 스트림으로 문자를 내보낼 때 버퍼링을 함으로써 문자, 문자 배열, 문자열 라인 등을 보다 효율적으로 처리할 수 있도록 함

 문자 입출력 스트림을 사용하는 경우에는 한 문자씩 읽지만, 버퍼링 기능을 추가하게 되면 입출력 스트림으로부터 미리 버퍼에 데이터를 갖다 놓기 때문에 보다 효율적으로 입출력이 가능함

 

<BufferedReader의 생성자>

BufferedReader의 생성자
설명
BufferedReader (Reader in)
주어진 문자 입력 스트림 in에 대해 기본 크기의 버퍼를 갖는 객체를 생성함
BufferedReader (Reader in, int size)
주어진 문자 입력 스트림 in에 대해 size 크기의 버퍼를 갖는 객체를 생성함

<BufferedReader의 주요 메서드>

BufferedReader의 메서드
설명
int read() throws IOException
한 문자를 읽어서 리턴함
int read(char buf[], int off, int len) throws IOException
문자 입력 스트림에서 len만큼을 읽어 buf[]의 off 위치에 저장하고 읽은 문자 수를 반환함
String readLine()
한 줄을 읽어서 리턴함

<BufferedWriter의 생성자>

BufferedWriter의 생성자
설명
BufferedWriter (Writer out)
주어진 문자 출력 스트림 out에 대해 기본 크기의 버퍼를 갖는 객체를 생성함
BufferedWriter (Writer out, int size)
주어진 문자 출력 스트림 out에 대해 size 크기의 버퍼를 갖는 객체를 생성함

<BufferedWriter의 주요 메서드>

BufferedWriter의 메서드
설명
void newLine() throws IOException
줄을 바꿈
void write(char buf[], int off, int len) throws IOException
주어진 문자 배열 buf[]의 off 위치부터 len만큼의 문자를 출력함
void write(String s, int off, int len) throws IOException 주어진 문자열 s의 off 위치부터 주어진 길이 len 만큼의 문자를 출력함

InputStreamReader / OutputStreamWriter

 바이트 스트림에서 문자 스트림으로, 또는 문자 스트림에서 바이트 스트림으로의 변환을 제공하는 입출력 스트림임

 바이트를 읽어서 지정된 문자 인코딩에 따라 문자로 변환하는데 사용함

 문자로 변환하는 경우 인코딩 방식은 특정 방식으로 지정할 수도 있고 경우에 따라서는 플랫폼의 기본 인코딩을 이용하기도 함

<inputstreamreader의 생성자>

InputStreamReader의 생성자
설명
InputStreamReader (InputStream in)
주어진 문자 입력 스트림 in에 대해 기본 인코딩을 사용하는 객체를 생성함
InputStreamReader
(InputStream in, String enc)
주어진 입력 바이트 스트림 in에 대해 enc 문자 인코딩을 사용하는 객체를 생성함

<InputStreamReader의 주요 메서드>

InputStreamReader의 주요 메서드
설명
String getEncoding()
현재 사용하고 있는 문자 인코딩의 표준 이름을 얻음

<outputstreamwriter의 생성자>

OutputStreamWriter의 생성자
설명
OutputStreamWriter (OutputStream out)
주어진 문자 출력 스트림 out에 대해 기본 인코딩을 사용하는 객체를 생성함
OutputStreamWriter
(OutputStream in, String enc)
주어진 출력 바이트 스트림 out에 대해 enc 문자 인코딩을 사용하는 객체를 생성함

<OutputStreamWriter의 주요 메서드>

OutputStreamWriter의 주요 메서드
설명
String getEncoding()
현재 사용하고 있는 문자 인코딩의 표준 이름을 얻음

SW Expert Academy

2072. 홀수만 더하기

Scanner와 BufferedReader를 사용하여 소스 코드를 제출했을 때를 비교해보자.

Scanner 사용

( 위의 이미지와 네이버 블로그 주소 제 것입니다! 티스토리로 글 옮기느라 주소가 첨부되었습니다. 양해 부탁드립니다 🙇‍♀️)

BufferedReader 사용​

· 코드길이

Scanner(406B) < BufferedReader(582B)

· 메모리

Scanner(20,420kb) > BufferedReader(16,076kb)

· 실행시간

Scanner(121ms) > BufferedReader(99ms)

Scanner는 입력 하나하나 받아 처리하지만, BufferedReader는 '버퍼' 말그대로 데이터를 버퍼에 보관하여 한 번에 전송하기 때문에 데이터양이 많을수록 Scanner보다 BufferedReader의 속도, 효율이 더 높을 수밖에 없다.

댓글