본문 바로가기
Language/Java

[java] 입출력함수

by okbear3 2021. 11. 5.

[자바 입출력 함수]

BufferedReader/BufferedWriter

백준에서 알고리즘 문제를 BufferedReader를 이용한 해설을 많이 볼 수 있습니다.
많은 데이터를 입력 받아야 하는 상황에는 BufferedReader를 이용하는 것이 좋습니다.
이 함수는 이름처럼 버퍼를 이용해서 읽고 쓰는 함수이기 때문에 이 함수를 이용하면 입출력의 효율이 비교할 수 없을 정도로 좋아집니다.

위의 그림에서와 같이 중간에 메모리 버퍼를 둬서 데이터를 한데 묶어서 전송하는 방식입니다.

버퍼(Buffer)는 데이터를 한곳에서 다른 한곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 임시 메모리 영역입니다.
BufferedReader : Scanner와 유사
BufferedWriter : System.out.println과 유사
Buffer flush : 버퍼에 남아있는 데이터를 출력시킴(버퍼를 비우는 동작)

버퍼함수는 기존에 쓰던 scanner와 system.out.println보다 속도 측면에서 훨씬 빠르기때문에 많은 양의 데이터를 처리할 때 유리합니다.
하지만 그에 비해 BufferedReader은 Enter만 경계로 인식하고 받은 데이터를 String 으로 고정시키기 때문에 입력받은 데이터를 가공하는 작업이 필요한 경우가 많습니다.

BufferReader

Buffer함수를 사용하기 위한 클래스 선언

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

BufferReader의 사용법

BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); //선언
String s = bf.readLine(); //String
int i = Integer.parseInt(bf.readLine()); //Int

입력은 readLine()이라는 메서드를 활용하는데 readLine의 경우에는 리턴값을 String으로 고정되기에 String이 아닌 다른 타입으로 입력을 받으려면 형변환을 해줘야 합니다.
그리고 readLine을 사용할 때 마다 try&catch를 활용하여 예외처리를 해주어야 합니다.(대개 throwsIOException을 이용합니다.)

*throwsIOException을 이용 시

//클래스 선언
import java.io.IOException; 

//main 클래스 옆에 throwsIOException을 작성합니다.
public static void main(String[] args) throwsIOException{

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));    //선언
    int N = Integer.parseInt(br.readLine());    //readLine으로 입력받을 데이터 ->String으로 입력받기 때문에 형변환 필요
    int[] arr = new int[N];

    StringTokenizer st = new StringTokenizer(br.readLine());
    for(int i=0; i<N; i++){
        arr[i] = Integer.parseInt(st.nextToken());
    }

    br.close();    //입력 스트림을 답고 사용하던 버퍼 해제

}

*try&catch를 이용시

import java.io.*;

class BufferedReaderEx1{
  public static void main(String[] args){
      try{
          BufferedReader br =new BufferedReader(new InputStreamReader(System.in));

          //파일에서 입력받을 경우
          FileReader fr = new FileReader("BufferedReaderEx1.java");
          BufferedReader br_f = new BufferedReader(fr);

          //String이 리턴값이라 형변환 필수! 라인단위로 끊는다
          int num = Integer.parseInt(br.readLine());
          br.close();    //입출력이 끝난 후 닫아주기

          //파일의 한줄 한줄 읽어서 출력한다.
          String line = "";
          for(int i=1;(line = br_f.readLine())!=null;i++){
              System.out.println(line);
          }
      }catch(IOException e){
            e.printStackTrace();
          System.out.println(e.getMessage());
      }
   }
}

readLine()으로 받아온 문자열 데이터 나누기

StringTokenizer st = new StringTokenizer(s); //StringTokenizer인자값에 입력 문자열 넣음
int a = Integer.parseInt(st.nextToken()); //첫번째 호출
int b = Integer.parseInt(st.nextToken()); //두번째 호출

String array[] = s.split(" "); //공백마다 데이터 끊어서 배열에 넣음

read한 데이터는 Line단위로만 나눠지기 때문에 공백 단위로 데이터를 가공하려면 따로 작업을 해줘야 하는데 다음과 같은 방법으로 할 수 있습니다.
StringTokenizer에 nextToken()함수를 쓰면 readLine()을 통해 입력받은 값을 공백단위로 구분하여 순서대로 호출할 수 있습니다.
그리고 String.split()함수를 활용하여 배열에 공백단위로 끊어서 데이터를 넣고 사용하는 방식입니다.

BufferedWriter

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));   //할당된 버퍼에 값 넣어주기
String s = "abcdefg";   //출력할 문자열
bw.write(s+"\n");   //버퍼에 있는 값 전부 출력 
bw.newLine();    //개행(엔터)역할
bw.flush();   //남아있는 데이터를 모두 출력시킴
bw.close();   //스트림을 닫음

BufferedWriter의 경우에는 버퍼를 잡아놓았기 때문에 flush()/close()를 반드시 호출해 주어 뒤처리를 해줘야 합니다.
그리고 System.out.print()와 마찬가지로 자동개행이 안되기 때문에 \n을 통해 따로 처리해주어야 합니다.

[출처]
https://jhnyang.tistory.com/92
https://m.blog.naver.com/ka28/221850826909