본문 바로가기
JAVA

자바 입력 & 출력

by enai 2019. 10. 8.

기본적으로 Scanner와 System.out.println으로 입력과 출력을 할 수 있다.

java.io 패키지의 BufferedReader와 BufferedWriter 클래스로 더 빠른 입출력이 가능하다.

(하지만 Scanner와 println이 사용하는 방법이 쉽다.)

 

Scanner와 BufferedReader, BufferedWriter에 대해 알아보겠다.

 

 

 

1. Scanner

 

java.util 패키지의 Scanner 클래스이다.

JDK1.5부터 추가되었으며, 사용 방법은 아래와 같다.

 

import java.util.Scanner;

public class Main {
  public static void main(String args[]) {
    //Scanner 클래스 객체 생성
    Scanner scan = new Scanner(System.in);
    //라인 단위로 입력 데이터를 받는다. (입력하고 엔터 친 데이터까지)
    String inputStr = scan.nextLine();
  }
}

 

nextLine() 외에도 여러 메서드가 있다.

 

boolean nextBoolean()
byte nextByte()
short nextShort()
int nextInt()
long nextLong()
double nextDouble()
float nextFloat()
String nextLine()

 

입력된 데이터의 형식에 맞춰 사용하면 된다.

만약 데이터 형식이 맞지 않는다면 imputMismatchException이 발생한다.

 

 

 

 

2. BufferedReader / BufferedWriter

 

BufferedReader와 BufferedWriter는 버퍼를 이용하기 때문에 입출력의 효율을 높일 수 있다.

 

 

1) BufferedReader

 

import java.io.*; //java.io 패키지에 포함된 클래스이므로 import 한다.

public class Main {
  public static void main(String args[]) {
  try {
    //BufferedReader 클래스의 객체를 생성한다.
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    //입력 데이터를 라인 단위로 받아온다.
    String line = br.readLine();
    //사용 완료 후 닫아준다.
    br.close();
  } catch(IOException e) {
    e.printStackTrace();
  }
}

 

BufferedReader를 생성할 때 함께 생성하는 InputStreamReader와 System.in부터 차차 정리해보자.

 

System.in은 자바의 표준 입출력을 위한 입출력 스트림 중에 하나이다.

System.in, System.out, System.err 이렇게 3가지가 제공된다.

자바 애플리케이션이 실행될 때 자동으로 생성된다.

 

System.in은 콘솔로부터 데이터를 입력받을 수 있게 해 준다.

 

 

InputStreamReader는 BufferedReader와 System.in을 연결해주는 역할을 한다.

바이트 기반 스트림을 문자 기반 스트림으로 변환하는 작업을 수행한다.

이때, OS의 기본 인코딩 문자로 변환하게 된다. 따로 인코딩을 지정하고자 한다면

InputStreamReader(System.in, encoding);

여기서 encoding 자리에 인코딩 정보를 String 형태로 넣어주어야 한다.

 

이렇게 BufferedReader를 생성하고,

readLine()으로 라인 단위의 입력 데이터를 받아온다. 리턴 타입은 String이다.

이렇게 라인 단위로 받아 온 데이터는 split이나 StringTokenizer로 문자열을 잘라 사용할 수도 있다.

(StringTokenizer를 BufferedWriter 예시에서 사용해보았다.)

그리고 필요한 데이터 타입으로 변환하여 사용하면 된다.

 

 

 

2) BufferedWriter

 

BufferedWriter 예제는 위의 BufferedReader 예제에서 받은 데이터를 출력하는 예제이다.

 

import java.io.*; //BufferedWriter를 사용하기 위함이다.
import java.util.*; //StringTokenizer를 사용하기 위함이다.

public class Main {
  public static void main(String args[]) {
  try {
    //BufferedWriter 객체를 생성한다.
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    
    String data = "100,200,300,400";
    
    //문자열을 콤마를 구분자로 하여 나누는 StringTokenizer를 생성한다.
    //참고로 data를 콤마로 나누면 "100", "200", "300", "400" 4개의 문자열이 나오는데,
    //이 문자열들을 토큰이라고 한다.
    StringTokenizer st = new StringTokenizer(data, ",");
    
    //StringTokenizer의 hasMoreTokens()는 토큰이 남아있는지 true, false로 알려준다.
    while(st.hasMoreTokens()) {
      //BufferedWriter의 write()로 출력한다.
      //nextToken()은 다음 토큰을 반환하라는 것이다.
      bw.write(st.nextToken());
      //newLine()으로 개행할 수 있다.
      bw.newLine();
    }
    
    bw.flush();
    bw.close();
  } catch(IOException e) {
    e.printStackTrace();
  }
}

 

BufferedWriter는 OutputStreamWriter와 System.out을 이용하여 객체를 생성한다.

System.out은 콘솔로 데이터를 출력하고,

OutputStreamWriter는 OS의 인코딩대로 문자로 변환하는 역할을 한다.

 

BufferedWriter는 write 메서드를 이용해 출력한다.

자동 개행이 되지 않으므로, 필요하면 예제처럼 newLine() 메서드를 이용한다.

출력 내용은 버퍼에 저장되며, 버퍼가 가득 차면 그 내용들을 출력 소스에 출력한다.

그렇게 버퍼를 비우고 다시 출력을 저장할 준비를 한다.

이런 식으로 버퍼가 가득 차면 출력 소스에 출력을 하기 때문에, 마지막 출력 부분은 버퍼에 남아 제대로 출력되지 못하고 프로그램이 종료될 수가 있다.

그래서 flush()나 close() 메서드로 버퍼에 남아있는 모든 데이터를 출력시켜주어야 한다.

 

 

StringTokenizer는 더 이상 설명하지 않고, 공식 문서 링크를 남겨놓겠다.

▶ Java Platform SE 7 - StringTokenizer

 

 

 

 

+) try-with-resource문으로 자동으로 자원을 반환시켜줄 수 있다. (JDK1.7부터 추가되었다고 한다.)

▷ try-with-resource

 

import java.io.*;

public class Main {
  public static void main(String args[]) {
  try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));) {
    
    String line = br.readLine();
    
    bw.write(line+"\n");
    
  } catch(IOException e) {
    e.printStackTrace();
  }
}

 

이렇게 try 옆 괄호 안에서 선언하면 close() 메서드 없이 close 된다.

입출력 클래스를 사용할 때 매우 유용할 것이다.

 

 

댓글