[JAVA] System 클래스(표준 입출력) : System.in, System.out, System.err

2019. 8. 6. 18:23 JAVA/Java IO

System 클래스(표준 입출력) : System.in, System.out, System.err


JAVA에서는 스크린과 키보드를 통한 입출력 방법인 표준 입출력을 제공한다. 표준 입출력을 제공하는 클래스는 java.lang.System으로 멤버 변수인 in, out, err을 이용해서 표준 입력, 표준 출력, 표준 에러를 제공한다.


1. System.in


System.in은 InputStream 형태로 지정되어 있다. System 클래스는 자바 버추얼 머신을 구성하고 있는 표준 장치를 뜻하는 클래스이다. 자바 버추얼 머신은 그 자체가 완벽한 하나의 컴퓨터 플랫폼을 가정하고 있기 때문에 독립적으로 동작할 수 있는 구조를 표현하기 위하여 표준 입력과 표준 출력을 스스로의 System 클래스에 등록하여 사용한다.


여기에서 주목해야 할 부분은 System.in 변수의 타입이 InputStream 이라는 점이다.

InputStream 클래스는 최상위 클래스이면서 추상 클래스이다. 따라서 InputStream은 객체를 생성할 수 없는 클래스이다.


[JAVA/Java IO] - [JAVA] ByteStream : InputStream / OutputStream


그런데도 System.in은 실제로 객체가 존재하고 있으며 이를 통하여 키보드 입력을 받을 수 있다. 이것은 변수의 타입은 선조 클래스이지만 실제 객체는 후손 객체이다. 자연스러운 형 변환이 지원되기 때문에 가능하다.


System.in을 통하여 접근되는 객체는 자바 버추얼 머신이 메모리로 올라오면서 미리 객체를 생성해 놓는, 대표적인 객체이다. 자료형이 InputStream이기 때문에 바이트 단위로만 입출력이 허용된다.

키보드에서 입력하는 자료는 때에 따라서 두 바이트가 합쳐져야 의미를 가지는 경우가 있다. 그래서 System.in을 통하여 읽을 경우에는 영문과 한글의 처리를 분리해서 구성해야 제대로 인식할 수 있다. 


2. System.out


System.out 변수는 표준 출력 장치 객체를 가리키는 대표적인 출력 변수이다. 자바 언어를 처음 배우자마자 사용하는 문장 중 하나가 System.out.println() 메소드다.


System.out은 PrintStream 타입으로 선언되어 있는데 PrintStream은 OutputStream 클래스의 후손 클래스로 Exception을 안전하게 처리한 메소드로만 구성되어 있다. 이런 이유로 System.out 을 이용하여 출력할 때는 try, catch 구문을 작성할 필요가 없다.



3. System.err


System.err 객체는 표준 에러 출력 장치를 의미하는데 일반적으로 System.out과 마찬가지로 모니터로 지정되는 경우가 많다. 일반적인 정상 출력은 System.out으로 나가고, 오류가 발생할 때 알려주어야 할 내용은 System.err로 나간다고 볼 수 있다. 이 변수의 타입도 PrintStream 클래스 타입으로 System.out을 사용하는 방법과 동일하다.



* System.in, System.out. System.err 예제


 

import java.io.IOException;


public class SystemTest {
   
    public static void main(String args[]){
       
        int bt;
        int cnt =0;

  

        try{

           
            // 표준 입력을 받는다.
            while((bt=System.in.read())!=-1){
                cnt++;
               
                // 입력받은 내용을 표준 출력한다.
                System.out.write(bt);
            }
           
        }catch(IOException e){
            //에러 발생시 에러를 출력한다.
            System.err.println(e);
        }
       
        System.out.println();
        System.out.println("totla bytes : "+cnt);
    }
}




- System.in 으로 문자를 1바이트씩 입력받아서 출력한 후, 총 바이트를 출력한다.

- 윈도우에서는 Ctrl-Z 를 누르면 EoF 로 System.in.read()가 -1 로 인식하여 while() 루프를 빠져나온다.


- 여기서 한글 입력을 받지 못하는 문제가 있다.

- System.in.read() 는 1바이트씩 받지만 한글은 문자당 2바이트이다. 따라서 위와 같은 방식으로는 한글을 사용할 수 없다.
- 해결방법으로는 1바이트씩 입력받은 값을 배열에 저장한 후 유니코드 계산과정을 통해 한글 문자로 변환해야 한다.
하지만 이러한 작업을 하는것 보다는 Scanner나 InputStream을 사용하는 것이 낫다.



JAVA API DOC : System 클래스



출처: https://hyeonstorage.tistory.com/235?category=578560 [개발이 하고 싶어요]