태투'S/SIL

2022_08_29 JAVA - I/O 클래스 BufferedReader 와 Bufferedwriter

태투2 2022. 8. 29. 16:43

txt 파일을 자바 프로그래밍으로 불러와서 필요한 데이터 값을 쿼리를 통해 파싱하는 과제를 부여 받았다.

올해 4월 이후에 자바 문법에 대한 공부를 그렇게 깊게 하지는 못했던 것 같다. 반성 또 반성하며 이번 과제를 통해 공부했던 것과 그 외에 것들에 대해 다시 정립해 나가게 되었다.

 

우선 위에 언급한 과제를 수행하기 위해서는 BufferedReaderBufferedwriter 클래스를 사용했는데, 대표적인 자바의 I/O(Input/Output) 클래스로 BufferedReader와 같은 경우는 Scanner와 같은 역할을 하고 Bufferedwriter는 System.out.println(); 와 같은 역할을 한다.

그럼 여기서 왜 ! 굳이 배웠던 Scanner 와 sout 클래스를 사용하지 않고 BufferedReader 와 Bufferedwriter 클래스를 이용하느냐?

아래 타 블로그에서 인용해 온 도식을 보면 이해하기 쉬울 것이다.

 

인용: SNUPI 티스토리 블로그 https://snupi.tistory.com/48

 

 

여기서 앞서 언급한 두 클래스의 차이는 크게 Scanner 클래스는 Space, Enter 모두 입력값을 인식하고, BufferedReader 클래스는 Enter만을 입력값을 인식한다.

아직 많은 양의 데이터를 가공하여 사용하지 않았지만, 아마 큰 용량의 데이터를 입력받아 가공할 때는 입력된 데이터가 바로 전달되지 않고 버퍼를 거쳐서 전달되는 BufferedReader 클래스가 데이터 처리의 효율성과 속도면에 훨씬 빠를 것이다.

 

예시 )) BufferedReader 클래스

package com.example.javabufferclass;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class ReaderTest {
    // BufferedReader는 Exception이 처리를 따로 해줘야 하기 때문에
    // throws를 해주거나 try-catch 로 예외처리를 해줘야 한다.

    public static void main(String[] args) throws Exception{
        // BufferedReader 객체 생성
        // new InputStreamReader 및 System.in
        BufferedReader br = new BufferedReader (new InputStreamReader(System.in));

        // StringTokenizer 객체 선언
        StringTokenizer st = null;

        // String Line 이므로 Integer.parseInt를 이용하여  형변환 해야함
        int n = Integer.parseInt(br.readLine());

        // "1 3 5 7" 식으로 공란 포함 String Line 일시 StringTokenizer 이용
        int[] arrays = new int[n + 1];
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= n; i++){
            // 배열마다 토큰을 하나씩 불러서 입력해줌
            arrays[i] = Integer.parseInt(st.nextToken());
        }
    }

}

예시 )) BufferedWriter 클래스

package com.example.javabuffercalss2;

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;

public class WriterTest {
    // BufferedWriter 역시 BufferedReader 와 마찬가지로
    // IOException 처리를 별도로 해줘야 한다.
    // 보통 Exception 으로 throws 시키곤 한다.
    // try - catch 가 편리하면 tru - catch 로 처리해도 상관없다.

    public static void main(String[] args) throws Exception{
        // BufferedReader 는 입력값을 바이트스트림에서 문자스트림으로
        // 변환해주는 InputStreamReader 와 입력장치를 통해 값을 입력받아주는
        // System.in 을 사용했다고 한다면 BufferedWriter 는 출력이므로
        // 그에 반대로 작동하는 OutputStreamWriter 와
        // System.out 을 사용한다.

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        // BufferedWriter 객체를 이용하여 출력한다.


        bw.write("Hello World!");
        // write 한다고 해서 곧 바로 출력되지 않는다.
        // 직접 출력 stream 에 반영되는 것이 아니라 성능을 위해
        // buffer 에 저장해뒀다가 BufferedWriter 가 flush 되거나
        // close 되었을 때 한 번에 출력 stream 에 반영하기 때문이다.

        bw.flush();
        // close 는 stream 을 닫아버리기 때문에 계속 출력하고자 하거나, 버퍼를 초기화하고자 한다면
        // flush 를 사용한다.


        bw.newLine();
        // 출력 내용에서 줄바꿈이 필요하다면 newLine 함수를 사용한다.

        bw.write("new line\n");
        bw.write("new line2");
        // newLine 함수 또는 \n 을 통해 출력값의 앞뒤에 넣어서 줄바꿈으로 출력하기도 한다.

        bw.close();
        // 자바의 경우 GC를 통해 buffer 클래스 내부의 객체들이 자동으로 정리가 된다.
        // 하지만 GC에 의해 사용되지 않은 자원이 정리되기 전에 반복적으로 buffer 클래스가 close 되지 않고
        // 정상적으로 read 나 write 가 되지 않을 수 있다.
        // 그러므로 buffer 사용 후 자원관리를 위해서 반드시 close 함수를 통해 buffer 클래스를 닫아 주자.
    }
}