티스토리 뷰

  모든 프로그래밍의 기본은 입출력(I/O)에서 시작된다. 프로그램이란 입력받은 데이터에 따라 결과를 연산하고 다른 시스템에 이를 전달 하는 것이다. 전달 받게되는 값을 우리는 출력값이라고 부른다. 모든 프로그램은 사용자가 데이터를 입력하는 방법이 존재해야 한다. 그리고 사용자는 그 결과를 받아내야한다. Java 언어에서 어떤 방식으로 프로그램에 입출력을 하는지 알아보자. 이번 글에대해 이해하기 위해서는 Java언어에서 변수의 종류와 선언 방법, 그리고 클래스 개념에 대해서는 기본적으로 숙지하고 있어야 이해하기 수월할 것이다. 


1. 콘솔 입력

  Java에서 입출력은 크게 2가지 방법으로 나뉜다. 바로 콘솔 입출력과 파일 입출력이다. 콘솔 입출력은 프로그램 실행 환경에 따라 각각 달라진다. Java의 경우 많은 사람들이 이클립스나 도스를 이용해 많이 개발 환경을 설정하는데 사용자가 직접 콘솔창을 통해 입력을 받거나 출력을 받는 경우를 의미한다. 콘솔 입출력 방법에 대해 자세히 알아보자.


- InputStream

  자바에서 기본적으로 사용하는 입력 방법은 InputStream 클래스를 이용하는 방법이다. InputStream은 java.io에 속해있는 클래스이므로 별도의 import가 필요하다. InputStream 클래스는 java에서 프로그램은 1byte씩 입력받을 때 사용하는 클래스이다. 우선 InputStream 클래스를 이용해 값을 입력하는 방법에 대한 사진을 보자



  입출력에 대한 간단한 입력 프로그램은 아래와 같이 만들 수 있다. 그에대한 결과는 아래와 같이 나온다.



  결과 값을 보면 알 수 있듯이 숫자 값 4를 입력했지만 결과값으로는 52가 출력 되었다. 이렇게 출력되는 이유는 InputStream 클래스의 경우 아스키코드로 값을 인식한다. 따라서 4에 해당되는 아스키코드값 52로 값을 저장하게 된다. InputStream클래스에서 값을 읽는 메소드는 read()이다. read메소드의 경우 반드시 int형의 값을 받게 된다. 길이에 대한 설정이 없다면 1byte에 해당되는 입력값을 위 처럼 아스키 코드 값으로 저장하게 된다고 생각하면 된다. 


  InputStream 클래스의 input 변수에 선언된 System.in은 JVM에서 표준 장치를 담당하는 System 클래스에서 값을 입력하는데 사용되는 클래스이다. System.in 클래스를 선언하게 되면, JVM은 입력값을 받을 수 있는 메모리를 확보하고 키보드를 통해 입력된 값을 메모리에 저장하게 된다고 생각하면 된다. 그리고, 해당 객체가 선언된 변수 (위에서는 input)에 그 값을 저장한다고 생각하면된다. 별도의 자료형이 정해져 있지 않기 때문에 InputStream을 선언해도 사용이 가능하다. 


  만약 InputStream 클래스를 통해 여러개의 값을 받아야 한다면 어떻게 해야 할까? InputStream 변수를 여러개 만들면 된다. 위의 예제를 기준으로 살펴보면 a를 배열 변수로 선언해서 a[0], a[1], ... a[n]에 대한 값을 각각 입력하면 된다. 그리고 그 배열에는 각각 입력한 값의 아스키 코드가 저장 될 것이다.


  InputStream클래스에 대해 더 자세한 점을 알아보고 싶다면 Oracle사에서 제공하는 아래 사이트를 참고하면 좋을 것이다.

https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html


- InputStreamReader

  InputStream의 단점 중 하나는 바로 모든 자료형을 아스키코드로 인식한다는 점이다. 사용자가 입력하는 값을 모두 아스키코드로 인식하기 때문에 자료형에 관계없이 입력할 수는 있으나 이를 이용해 프로그램을 짜기 매우 힘들게 된다는 단점이 발생된다. 이를 해결한 클래스가 바로 InputStreamReader이다. 


  위의 사진은 InputStreamReader를 이용하여 만든 입력 코드이고, 아래는 결과 값이다.



  앞서 InputStream이 문자를 바이트단위의 아스키코드로 인식하는 것과 달리 이경우 문자를 그대로 인식하게 된다. char형 객체를 이용해 입력받은 값을 저장하게 된다. InputStreamReader는 반드시 InputStream클래스를 통해 선언되어야 한다. InputStream 변수를 아스키코드가 아닌 문자형으로 설정하는 것이다. 또한, InputStreamReader 는 InputStream의 하위 클래스가 아니기 때문에 상속이 안되므로 별도로 선언해야 한다. 두 클래스 모두 java.io의 하위 클래스이다.


- BufferedReader

  사용자 친화적인 문자열 그대로 받는 방법인 InputStreamReader클래스를 이용했어도 불편함은 여전히 남아있다. 바로 문자열의 값이 고정이라는 점이다. 프로그램을 진행할 때 미리 정해 놓은 길이 만큼의 변수만 인식하게 된다. 이런 문제를 해결할 수 있는 클래스가 바로 BufferedReader이다. 우선 코드를 한번 살펴보자.

 


  BufferedReader는 InputStreamReader로 읽어 들인 변수를 가변 크기로 읽는데 사용되는 클래스이다. 따라서 InputStreamReader변수를 BufferedReader로 선언하여 위와 같이 표현하게 된다. BufferedReader역시 InputStreamReader클래스의 상위 클래스가 아니므로 다형성은 당연히 성립되지 못한다. 사용자가 값을 입력하고 종료를 뜻하는 엔터를 누르기 전까지 문자를 인식하지 않고 있다가 한번에 인식하게 된다. 



  BufferedReader는 미리 크기를 선언해도 되지 않는 String 형태의 변수로 인식한다. 즉 Java의 입출력 함수에서 사용되는 3개의 클래스는 결국 받아내는 변수가 다르다는 점이다. InputStream은 int형, InputStreamReader는 char[]형, BufferedReader는 String으로 인식하게 된다. 뒤에 배울 Scanner 입력방식과의 가장 큰 차이점이 바로 입력 자료형이 정해져 있다는 점이다.

- Scanner

  InputStream은 Java에서 제공하는 가장 기본적이고 컴퓨터적인 입력방법이다. 컴퓨터는 문자가 인식하는 방법은 비트의 집합인 바이트로 인식을 하며, 그 담위로 입력을 받기 때문에 InputStream은 매우 컴퓨터 친화적이다. 하지만 사람이 입력하기엔 매우 불편하다. 우리가 프로그래밍을 하면서 아스키코드로 인식하는 프로그램을 짜는 일은 극히 드물기 때문이다. 이는 컴퓨터가 처리할 일이지 개발자와 사용자에게 편리한 방법은 전혀 아니다. 

  또 다른 문제점은 InputStream의 경우 입력값에 대한 고정된 크기를 미리 설정해주어야 한다는 점이다. 물론 위 문제를 버퍼 공간을 미리 확보해 자료를 저장받는 방법인 BufferedReader클래스로 해결 할 수는 있지만, 입력을 위해서 총 3개의 클래스와 변수 선언이 필요하다는 점, String 자료형에 한정되어 사용된다는 점이 걸린다.


  그래서 J2SE 5.0 버전 이후부터 Scanner라는 클래스가 새로 추가되었다. Scanner의 장점은 입력받는 값이 자료형의 구분이 별도로 필요하지 않다는 점이다. 프로그램에서 선언된 변수에 따라 값을 읽게 된다 아래의 프로그램을 보자. 




  이처럼 Scanner클래스는 선언하는 변수에 상관 없이 적용 할 수 있다. Scanner 클래스에 저장되어있는 메소드들로 입력값을 구분하게 되는데, 대표적으로 사용하는 3가지 함수가 위에 있는 nextLine(), next(), nextInt()이다.


  • next(): 글자를 단어 단위로 읽는 메소드
  • nextLine(): 글자를 문장 단위로 읽는 메소드
  • nextInt(): int형 값을 읽는 메소드


  이 외에도 다양한 종류의 메소드가 있다. 자세한 사항은 아래 링크를 참고하면 된다.

https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html



2. 콘솔 출력

  콘솔 입력에서 System.in 클래스를 이용해 사용자가 입력을 진행했다면 출력의 경우 System.out 클래스를 이용해서 출력하면 된다. 앞서 많은 예시 화면에서 보여준대로 System.out.println()을 선언하여 원하는 값을 출력하면 된다. Java.lang에 속한 System객체를 통해 JVM에서 필요한 다양한 입출력을 처리할 수 있다. 


  System.out의 강점 중 하나는 별도의 try/catch문을 작성할 필요하 없다는 점이다. 예외처리가 모두 완료된 결과 값 만을 출력하기 때문에 단 한줄의 문장으로도 쉽게 출력 값을 내보낼 수 있다.


  

  이클립스에서 프로그램 테스트나 디버깅을 진행할 때 많이 콘솔을 통한 입출력을 사용한다. 프로그래밍을 하면서 직접적으로 사용되지는 않지만, 우리의 결과를 직관적으로 볼 수 있는 가장 좋은 방법이고, 또한 가장 많이 사용하게 된다.


  오늘날 자료 입력은 Scanner 클래스를 대부분 이용하기는 하지만, InputStream을 통해 Java가 어떤 방식으로 값을 저장 받고 처리하는 지에 대해서 알 수 있었다. 프로그램 입력을 위해서 우리가 지정해 주어야 하는 것, 그리고 이를 위해서 우리가 선언하는 클래스 등에 대해서 알아보았다.


  다음 시간에는 테스트, 디버깅에 사용하는 콘솔이 아닌 실제 프로그램에서 많이 사용하는 파일 입출력에 대해서 알아볼 것이다. 대부분의 실제 프로그램들은 파일을 통해 입력 값을 주고 받게 된다. Java 프로그램에 파일을 입력하게 출력하는 과정을 배워보자.

'Skill > Programming - Basic' 카테고리의 다른 글

6.알고리즘 시간복잡도  (0) 2018.02.27
5. Brute Force Algorithm  (0) 2018.02.22
4. Java 입출력 함수 - 파일 입출력  (0) 2018.02.15
2. 수학적 귀납법  (0) 2018.01.25
1.논리와 명제  (0) 2018.01.24
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함