본문 바로가기

Java

java IO) Buffered Stream 보조 기반 스트림

문자 기반 스트림은 바이트 기반 스트림보다는 편리하지만

만약 텍스트 글자가 100만자라면

처리하는데 엄청나게 많은 시간이 걸릴 수 밖에 없다.

기능의 확장이 필요하다.

보조 기반 스트림

Buffered Stream

 

버퍼란 데이터를 전송하기 위해 일시적으로 사용하는 공간이다.

버퍼를 사용하면 많은 양의 데이터를 효율적으로 처리할 수 있다.

 

예제1)

키보드 입력값을 받아, 화면에 출력하는 스트림을 만들어보자

1.입력스트림 준비

2.출력스트림 준비

3.버퍼 도구 준비

4.실행의흐름(while)

package ch04;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;

/** 5.29 보조 기반 스트림
 기반 스트림이 있어야 사용할 수 있다
 InputStream, InputStreamReader.. */

public class ByteBufferedKeyboardConsole {
    public static void main(String[] args) {
        //바이트 기반 스트림 + 버퍼드 스트림
//        BufferedInputStream bis = new BufferedInputStream(System.in);
//        BufferedOutputStream bos = new BufferedOutputStream(System.out);

        try(BufferedInputStream bis = new BufferedInputStream(System.in);
            BufferedOutputStream bos = new BufferedOutputStream(System.out)){
            /*보조스트림을 활용해
            한번에 1024바이트 크기의 버퍼배열로 데이터를 읽자*/

            //버퍼 도구 준비
            byte[] buffer = new byte[1024];
            int bytesRead;
//            bis.read(); //한번에 1바이트씩 읽는다
//            bis.read(buffer);// 한번에 1024 크기만큼 읽는다

            while ((bytesRead = bis.read(buffer)) != -1) {
                //System.out.println()
                bos.write(buffer, 0, bytesRead);
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }//main
}//class

 

예제2)

문자열 기반 스트림 + 버퍼드 스트림

1.입력스트림 준비 + 버퍼드 스트림

2.출력스트림 준비 + 버퍼드 스트림

3.실행의 흐름(while)

public class CharBufferedKeyboardConsole {
    public static void main(String[] args) {

        /* InputStreamReader 는 System.in(InputStream) 을 기반으로 한다.
        BufferedReader 는 InputStreamReader 를 래핑 wrap 해서 사용한다.

         기능의 확장!
         상속(수직적)과는 달리 수평적으로 확장되고 있다.
         이런 구조를 데코레이션 패턴이라고 한다. */

        try (InputStreamReader isr = new InputStreamReader(System.in);
             BufferedReader br = new BufferedReader(isr);
             PrintWriter pw = new PrintWriter(System.out);
             BufferedWriter bw = new BufferedWriter(pw)) {

            System.out.println("텍스트를 입력하세요(종료 빈줄 입력)");

            /* readLine() 메서드는 문자열의 한 줄을 그대로 읽는다
            null 은 입력의 끝을 의미한다
            혹시 인텔리제이에서 종료가 안될때는
            Ctr D 또는 Ctr Z를 누르면 된다. */

            String line;
            while ((line = br.readLine()) != null && !line.isEmpty()) {
                bw.write(line.replace("자바","java"));
                bw.newLine();
                bw.flush();
            }

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("스트림 사용중 오류 발생:" + e.getMessage());
        }//t-c
    }//main
}//class

 

예제3)

파일 입출력 + 버퍼드 스트림

1.경로준비

2.파일 입력 스트림 + 버퍼드 스트림

3.파일 출력 스트림 + 버퍼드 스트림

4.버퍼 도구 준비

5.실행의 흐름

public class FileCopyBuffered {
    public static void main(String[] args) {
        //파일 경로 지정
        String sourceFilePath = "employees.zip";
        String destinationFilePath = "employees_copy.zip";
        //소요시간 측정
        long startTime = System.nanoTime();

        try (FileInputStream fis = new FileInputStream(sourceFilePath);
             FileOutputStream fos = new FileOutputStream(destinationFilePath);
             BufferedInputStream bfis = new BufferedInputStream(fis);
             BufferedOutputStream bfos = new BufferedOutputStream(fos)) {

            byte[] bytes = new byte[1024];
            int data;
            while ((data = bfis.read(bytes)) != -1) {
                bfos.write(bytes,0,data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //소요시간 계산
        long endTime = System.nanoTime();
        long duration = endTime - startTime;
        System.out.println("10억분의 1초"+ duration);
        System.out.println("초:"+duration/1_000_000_000);
    }//main
}//class

지정한 경로대로 파일복사가 완료됐다
버퍼드 스트림을 사용한 덕분에, 파일 복사에 소요되는 시간도 0.34초로 대폭 줄어들었다.

 

예제4)

키보드입력값, 파일에 출력 feat.버퍼드스트림

1.파일경로

2.입력스트림(키보드) + 버퍼드 스트림

3.출력스트림(파일) + 버퍼드 스트림

4.실행의흐름

public class StreamTest {
    public static void main(String[] args) {
        String destinationFilePath = "test.txt";
        System.out.println("문자열을 입력해주세요");
        try (
//             InputStreamReader isr = new InputStreamReader(System.in);
//             BufferedReader br = new BufferedReader(isr);
//             FileWriter writer = new FileWriter(destinationFilePath, true);
//             BufferedWriter bw = new BufferedWriter(writer)

                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                BufferedWriter bw = new BufferedWriter(new FileWriter(destinationFilePath, true))
        ) {
            String line;
            while ((line = br.readLine()) != null && !line.isEmpty()) {
                bw.write(line);
                bw.newLine();
            }//while
            bw.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }//try-catch
    }//main
}//class

 

1.입력스트림, 버퍼드 스트림을 따로 썼던 구문을 한줄로 축약했다.

2.파일출력스트림 생성자에 경로와 함께 append 모드(추가모드)를 활성화했다/ append: true

append 모드를 켜면, 파일의 기존 내용을 덮어쓰지 않고 추가할 수 있게 된다.