JAVA 입출력

김정욱·2022년 12월 21일

공부📚

목록 보기
1/4
post-thumbnail

입력이란?

  • 외부에서 받은 데이터를 프로그램 내부 공간인 메모리로 옮기는 행위이다.
  • 콘솔을 통해 입력받은 모든 데이터는 System.in(Standard input buffer)이라는 공간으로 들어오고 이 버퍼를 적당한 양식으로 데이터를 절단하여 프로그램 내의 지정한 메모리 상의 위치로 옮기게 되는 것이다.

1) Scanner

공란과 개행(space, enter)로 입력값의 경계를 결정한다. 입력받은 즉시 자료형이 확정되며, 자체적으로 Exception이 처리가 가능하게 정의되어 있는 클래스이다. 입력 받고 바로 메모리에 전달하는 방식.
장점은 사용하기에 편리하고 용이하나, 처리시간이 상대적으로 길다.

import java.util.Scanner;
// Scanner 클래스를 import 해줘야 사용 가능.

public class Main{
	public static void main(String[] args){
    	Scnnaer sc = new Scanner(System.in);
    }
}    

2) BufferedReader

이 클래스는 버퍼를 이용하는 대표적인 input/output 클래스이다.
라인 단위로 입력을 받는다. 즉 개행(enter)이 입력값의 경계를 결정한다. 그렇기 때문에 한줄에 공란(space)를 기준으로 여러 값들을 입력했다면 split을 해주어야한다.
또한 모든 입력값은 String의 형태로 인식하므로 필요한 자료형으로 변환도 필요하다.
Scanner와 달리 Exception이 없기 때문에 throws Exception을 해주어야 한다.
입력된 데이터를 바로 메모리에 전달하는게 아니라 버퍼에 저장해 두었다가 전달하기 때문에 처리시간이 빠르다는 장점이 있다. 데이터의 양이 적을 때는 큰 차이가 없지만 데이터의 양이 많아지게 되면 속도면에서 Scanner와 차이를 보이게 된다.

import java.io.*;

public class Main{

	public static void main(String[] args) throws IOException{
    	InputStream is = System.in; 
   	 		// byte stream, 입력받는 스트림
    	InputStreamReader isr = new InputStreamReader(is);
   			// byte stream을 문자 stream으로 정리
    	BufferedReader br = new BufferedReader(isr);
    		// 문자 stream 을 다시 정리하여 문자열 stream으로
    	// 만약 받은 데이터를 정수형으로 처리하고 싶다면..
    	Integer.parseInt()를 사용하여 Stringint로 변환필요
       
    	String line = null;
        for(int i = 0; i < 2; i++){
        	line = br.readLine();
        }
        int num = Integer.parseInt(line);
        br.close();
    }    
}

Scanner는 편리성 대신 처리속도의 지연
BufferedReader는 처리속도가 빠른대신에 코드의 불편함이 있다.

i n p u t이라는 단어를 입력 받는다고 한다면

Scanner의 경우 i 입력받고 공란과 개행을 입력값의 경계로 하기 때문에 i를 메모리에 올리고 n 입력받고 메모리에 올리고를 반복하게 된다. 메모리에 올리는 과정에서 시간이 지연된다.

BufferedReader의 경우 버퍼에다가 i"공란"n"공란"p"공란".. 쭉쭉하다가 enter(개행)를 치면 i n p u t을 한번에 메모리에 올리게 되는 것이다. 그러므로 처리속도는 빠르지만 이를 위해 필요한 코드들을 입력해줘야한다.

출력이란?

  • 출력은 메모리에 있는 데이터를 출력 스트림에 쏟아내고 스트림을 통해 화면에 랜더링되는 방식이다.
  • 이때 데이터를 쏟아내는 행위(flush)의 시간 소모가 크다.
  • 2가지의 시간 소모 부담 요소가 존재한다.
    -- 데이터를 쏟아내는 방식
    -- 출력 스트림에 접근하는 방식

1) StringBuilder

StringBuilder 클래스는 메모리에서 문자열을 만들어 가다가 한번에 쏟아내어 랜더링 하는 방식. 즉, 문자열 데이터를 메모리 상에서 빌드업하는 역할을 수행한다.

output을 출력한다고 했을 때 "o" "u" "t" "p" "u" "t" 을 쏟아내는 것과 "output"을 한 번에 출력하는 것에는 효율적인 차이가 있다. 6번의 flush가 아니라 1번의 flush를 하게 하는 것이다.

이처럼 데이터를 메모리 상에 빌드하고 출력하는 것이 StringBuilder 이다.

import java.util.*;

public class Main{
	public static void main(String[] args){
    	Scanner sc = new Scanner(System.in);
        StringBuilder sb = new StringBuilder();
       
        for(int i = 0; i < 3; i++){
        	String line = sc.nextLine();
            // "java" enter "공부" enter "화이팅" enter
            sb.append(line + '\n');
        }

        System.out.print(sb);
// 출력 java
//	   공부
//	   화이팅

for문에서 3번의 print를 수행하지 않고 StringBuilder를 이용하여 메모리에 빌드하였다가 한 번에 출력하였다.

2) BufferedWriter

위에서 설명한 BufferedReader랑 같은 개념이고 입력 대신에 출력으로 바뀐것이다.

import java.io.*;
import java.util.Scanner;

public class Main{

	public static void main(String[] args) throws IOException{
    	OutputStream os = System.out; 
   	 		// byte stream, 출력 스트림
    	OutputStreamWriter osw = new OutputStreamWriter(os);
   			// byte stream을 문자 stream으로 정리
    	BufferedWriter bw = new BufferedWriter(osw);
    		// 문자 stream 을 다시 정리하여 문자열 stream으로
      
		Scanner sc = new Scanner(System.in);
       
        for(int i = 0; i < 2; i++){
        	String line = sc.nextLine();
            bw.write(line + '\n');
        }
        bw.flush();
        bw.close();
    }    
}
profile
절박한 마음을 갖고 하루를 보내자!!

0개의 댓글