입력과 출력은 프로그램의 가장 기본 기능이지만, 외부 저장 장치나 네트워크와 연동해야 하기에 장치에 따라 다르게 구현해야 한다. 자바는 장치에 따라 독립적인 입출력 기능을 제공한다.
스트림이란?
자바에서 모든 입출력은 스트림을 통해서 이루어진다. 스트림이라는 용어는 자료의 흐름이 물의 흐름과 같다는 의미에서 사용되었다. 입출력 장치는 매우 다양하기 때문에 이를 각각 다르게 구현하면 당연히 프로그램 호환성이 떨어진다. 이런 문제를 해결하기 위해 자바는 입출력 장치와 무관하고 일관성 있게 프로그램을 구현할 수 있도록 가상 통로인 스트림을 제공한다. 자료를 읽어들이는 소스와 대상에 따라 각각 다른 스트림 클래스를 제공한다.
자바에서 입출력 기능을 사용하는 곳은 파일 디스크, 키보드, 모니터, 메모리 입출력, 네트워크 등이 있다. 이러한 곳에서 일어나는 모든 입출력 기능을 스트림 클래스로 제공한다. 구현 방식은 서로 비슷하다!
스트림을 세 가지 기준으로 분류해보자.
입력 스트림과 출력스트림
어떤 대상으로부터 자료를 읽어 들일 때 사용하는 스트림이 입력 스트림이다. 어떤 동영상을 재생하기 위해 동영상 파일에서 자료를 읽을 때 사용한다. 편집 화면에서 사용자가 쓴 글을 파일에 저장할 떄는 출력 스트림을 사용한다. 스트림은 단방향으로 자료가 이동하기 때문에 입력과 출력을 동시에 할 수 없다.
InputSteam / Reader로 끝나는 이름의 클래스는 입력 스트림이다.
OutputStream이나 Writer로 끝나는 이름의 클래스는 출력 스트림이다.
바이트 단위의 스트림과 문자 단위 스트림
자바의 스트림은 바이트 단위로 자료의 입출력이 이루어진다. 그러므로 그림, 동영상, 음악 파일 등 대부분의 파일은 바이트 단위로 읽거나 쓰면 된다. 그러나 자바에서 하나의 문자를 나타내는 char 형은 2바이트이기에 1 바이트만 읽으면 한글 같은 문자는 깨진다. 따라서 입출력 중 가장 많이 사용하는 자료인 문자를 위해 문자 스트림을 별도로 제공한다.
즉, 읽어들이는 자료형에 따라 바이트 용과 문자용 스트림이 있다.
스트림 클래스 이름이 Stream 으로 끝나는 경우 - 바이트 단위를 처리하는 스트림
Reader/ Writer 로 끝나는 경우 - 문자를 위한 스트림 클래스
기반 스트림과 보조 스트림
어떤 스트림이 자료를 직접 읽거나 쓰는 기능을 제공하는 스트림인가 아니면 부가 기능을 제공하는가에 따라 기반 스트림과 보조 스트림으로 구분할 수 있다. 기반 스트림은 읽어 들일 곳이나 써야할 곳에서 직접 읽고 쓸 수 있고, 입출력 대상에 직접 연결되어 생성되는 스트림이다. 반면 보조 스트림은 직접 읽고 쓰는 기능은 없다. 그래서 항상 다른 스트림을 포함하여 생성한다. 이름만으로 기반스트림인지 보조 스트림인지 판단하는 것은 어렵다.
표준 입출력
자바에서는 화면에 출력하고 입력받는 표준형 클래스를 미리 정의해두었다. 프로그램이 시작될 떄 생성된다.
자료형 - static PrintStream / 변수 이름- out / 설명 - 표준 출력 스트림
자료형 - static InputStream / 변수 이름- in / 설명 - 표준 입력 스트림
자료형 - static OutputStream / 변수 이름- err / 설명 - 표준 오류 출력 스트림
우리는 그동안 시스템 클래스를 생성하지 않았는데도 System.out 을 사용할 수 있었다. 그 이유는 정적 변수이기 떄문이다.
package stream;
import java.io.IOException;
public class SystemInTest1 {
public static void main(String[] args) {
System.out.println("알파벳 하나를 쓰고 엔터를 누르세요.");
int i;
try {
i = System.in.read(); //한 바이트 읽음
System.out.println(i);
System.out.println((char) i); //문자로 변환하여 출력한다.
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.in으로 화면에서 문자를 입력받는 프로그램을 구현해보았다. 입출력에 관한 코드를 구현하면 예외처리를 해야한다! 위 코드에 대해 설명해보자면, 알파벳을 하나 쓰고 엔터를 누르면 입력한 값이 변수 i에 들어간다. i 는 4바이트지만 System.in은 바이트 단위를 읽어들이는 InputStream 이므로 1바이트만 읽는다.
그 외 입력 클래스
scanner 클래스
스캐너 클래스는 java.util 패키지에 있는 입력 클래스이다. 문자뿐만 아니라 정수나 실수등 다른 자료형도 읽을 수 있다.
콘솔 화면 뿐 아니라 파일이나 문자열을 생성자의 매개변수로 받아 자료를 읽어올 수 있다.
Scanner 클래스는 System.in으로 입력받는 것보다 더 다양한 메서드를 활용할 수 있기 때문에 자주 사용하는 클래스이다.
package stream;
import java.util.Scanner;
public class ScannerTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("이름: ");
String name = scanner.nextLine(); //문자열을 읽는 nextLine() 메서드로 이름과 직업 입력을 받는다.
System.out.println("직업: ");
String job = scanner.nextLine();
System.out.println("사번:");
int num = scanner.nextInt(); //int형을 읽는 nextInt() 메서드로 사번을 입력받는다.
System.out.println(name);
System.out.println(job);
System.out.println(num);
}
}
이름과 직업은 문자열이므로 nextLine() 메서드로 입력받고, 사번은 정수이므로 nextInt 메서드를 사용했다.
Scanner은 다양한 자료형을 입력받을 수 있어서 많이 활용한다.
Console 클래스
System.in을 사용하지 않고 간단하게 콘솔 내용을 읽을 수 있는 클래스도 있다. 직접 콘솔 창에서 자료를 입력받을 때 이 클래스를 사용한다. 통합 개발 환경에서는 콘솔 클래스가 연동되지 않는 경우가 있어서 주로 Scanner 을 더 많이 이용한다.
'공부 STUDY > JAVA' 카테고리의 다른 글
[JAVA] 자바 입출력과 스트림 - (3) | 바이트 단위 스트림 - OutputStream (0) | 2023.01.24 |
---|---|
[JAVA] 자바 입출력과 스트림 - (2) | 바이트 단위 스트림 - InputStream (0) | 2023.01.24 |
[JAVA] 사용자 정의 예외 클래스 구현하기 | 아이디 설정 조건에서 예외 발생에대한 클래스를 구현해보자! | 사용자 정의 예외 (0) | 2023.01.23 |
[JAVA] 자바의 예외처리(Exception) | try-catch-finally 문, try-with-resource 문 (0) | 2023.01.23 |
[JAVA] 람다식이란? 람다식 사용 방법에대해 알아보자! (1) | 2023.01.23 |