[JAVA] JAVA 콘솔 입출력 정리
이번엔 JAVA 의 콘솔 입출력에 대해서 알아보도록 하겠습니다. 콘솔 입출력에 대해서 알아보기 전에 아마도 파일 입출력을 사용하면 되지 콘솔 입출력은 왜 사용하나요 하시는 분이 계실 수도 있습니다. 이에 대해서 저는 개인적으로 오류가 발생한 특정 케이스들을 단독으로 처리할 때에는 파일 입출력 보다는 콘솔 입출력으로 작업하는 것이 훨씬 더 수월했기 때문에 JAVA 의 입출력을 다루면서 콘솔 입출력을 먼저 다루게 되었습니다. 이는 개인적은 선호도 차이라고 생각을 해서 만약 콘솔 입출력 보다는 파일 입출력이 편하신 분들은 본 포스트를 굳이 안보셔도 될 것 같습니다.
콘솔 입력
콘솔 입력은 콘솔에 입력한 것을 받아와 코드에서 사용하고자 하는 것을 의미합니다. 콘솔은 명령 프롬프트 창이 될 수도 있고, JAVA 의 경우 이클립스나 인텔리제이와 같은 IDE 를 주로 사용하므로 IDE 의 콘솔이 될 수도 있습니다.
입출력과 관련해서 JAVA 는 여러가집 방식의 입출력이 존재하나 JAVA 에서 주로 사용하는 Steam 방식에 대해서만 다뤄보도록 하겠습니다.
자세한 것은 예시를 이용해 알아보도록 하겠습니다.
스트림이란?
우선 JAVA 의 콘솔 입력을 알아보기 전에 JAVA 에서 사용하는 스트림에 대한 개념을 간단하게 알아보도록 하겠습니다.
스트림(Stream)은 Byte 형태로 데이터를 운반하는데 사용되는 연결통로라고 생각하시면 됩니다. 이는 자료(data)의 흐름이 물의 흐름과 같다는 의미에서 사용되었다고 합니다.
스트림은 단방향 통신만 가능하며, 이 때문에 하나의 스트림으로 입력과 출력을 동시에 처리할 수 없습니다. 또한 스트림은 먼저 보낸 데이터를 먼저 받게 되어 있으며 연속적으로 데이터를 주고 받는다는 점에서 큐(queue)의 FIFO(First in First Out) 구조로 되어 있습니다.
스트림은 스트림의 근원지(시작점)을 Source, 데이터 종착점을 Sink, 이를 연결한 것을 Stream 이라고 표현하며, Source - input Stream - output Stream - Sink 로 연결됩니다.
정리를 하자면 스트림(Stream)은 Byte 형태로 데이터를 운반하는데 사용되는 연결통로로써 단방향 통신을 하며, 큐의 FIFO 구조로 되어 있습니다. 그리고 입력과 출력을 동시에 수행하려면 입력을 위한 입력 스트림(input stream)과 출력 스트림(output stream), 모두 2개의 스트림이 필요합니다.
InputStream
InputStream 은 바이트(byte) 단위의 데이터를 읽어 들일 때 사용하는 내장 클래스입니다.
자세한 내용은 예제 코드를 통해 알아보도록 하겠습니다.
import java.io.IOException;
import java.io.InputStream;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
int a;
a = in.read();
System.out.println(a);
}
}
콘솔 입력
a
출력결과
97
위 코드를 실행했을 때 a
를 입력하나 abc
를 입력하나 a
의 아스키 값인 97이 출력이 됩니다. 이에 대한 원인은 InputStream 의 경우 입력된 데이터에서 1byte 만 읽기 때문입니다.
InputStream 을 이용해 abc
전부를 읽게 하려면 다음과 같이 하면 됩니다.
import java.io.IOException;
import java.io.InputStream;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
int a;
int b;
int c;
a = in.read();
b = in.read();
c = in.read();
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
콘솔 입력
abc
출력 결과
97
98
99
InputStreamReader
위에서 InputStream 을 이용한 방법을 알아 보았습니다. 하지만 InputStream 은 한 번에 1byte 씩만 읽고, 읽어 들인 값을 항상 아스키코드 값으로 해석해야 해서 사용하기에는 굉장히 불편합니다.
InputStreamReader 는 바이트 단위로 읽어 들이는 InputStream 을 통해 입력을 받은 뒤, 문자(char) 단위로 데이터를 변환시키는 중개자 역할을 하는 클래스입니다.
하지만 JAVA 는 문자열 처리에 String 이 있어 특별한 경우를 제외하곤 InputStreamReader 를 자주 사용하지는 않을 것 같습니다. 하지만 그래도 이번 기회에 한 번 알아보도록 하겠습니다.
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Sample {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
InputStreamReader reader = new InputStreamReader(in);
char[] a = new char[3];
reader.read(a);
System.out.println(a);
}
}
콘솔 입력
abc
출력 결과
abc
확실히 InputStream 과는 다르게 char 배열만 있어도 입력을 모두 받을 수 있다는 점에서 더 편리한 것 같습니다. 하지만 그래도 아직까지 한계가 존재합니다.
입력은 얼마가 들어올지 알 수 없는데 char 배열은 크기를 지정해 주어야 해서 메모리 낭비가 발생할 수 있으며, JAVA 에서 주로 사용하는 String 이 아닌 char 를 사용하기 때문에 String 으로 바꾸는 추가 작업이 더 필요할 수 있습니다.
BufferedReader
InputStream 과 InputStreamReader 는 고정된 길이만 읽을 수 있었고, InputStream 은 강제로 아스키 값으로 바꾸어 주고, InputStreamReader 는 char 만 사용해야 하는 제한이 있었습니다.
이러한 제한을 모두 해결한 것이 있는데 그것이 바로 BufferedReader 입니다. BufferedReader 는 입력을 String 으로 받아옵니다. 자세한 것은 예제를 통해 확인해 보도록 하겠습니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Sample {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String a = br.readLine();
System.out.println(a);
}
}
콘솔 입력
abc
콘솔 출력
abc
위 코드에서와 같이 BufferedReader 를 쓰면 간단하게 String 으로 받아올 수 있습니다.
콘솔 출력
콘솔 출력으로는 System.out 을 사용합니다. System.out 은 PrintStream 클래스의 객체입니다. 주로 사용하는 System.out 은 줄바꿈이 없는 System.out.print, 줄바꿈이 있는 System.out.println 이 두 가지를 이용해 콘솔 출력을 할 수 있습니다.
Comments