카테고리 없음

[TIL] 2022년 9월 19일 월요일

2022. 9. 19. 20:03

3. 바이트기반의 보조스트림

3.1 FilterInputStream과 FilterOutputStream

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/FilterInputStream.html
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/FilterOutputStream.html

- FilterInputStream과 FilterOutputStream은 각각 InputStream과 OutputStream의 자식 클래스이면서 보조스트림 클래스의 조상 클래스

- FilterInputStream/FilterOutputStream은 보조스트림으로 자체적으로 입출력을 수행할 수 없고 InputStream과 OutputStream이 필요함

 

- FilterInputStream/FilterOutputStream은 각각 InputStream과 OutputStream의 모든 메소드를 상속받을 수 있고 상속을 통해 원하는 작업을 수행하도록 오버라이딩해야 함

- FilterInputStream은 접근제한자가 protected로 인스턴스를 생성할 수 없고 상속을 통해 오버라이딩 해야함

 

 

3.2 BufferedInputStream과 BufferedOutputStream

http://www.tcpschool.com/c/c_io_console

- 버퍼란 임시메모리 공간으로 위 그림에서 키보드로 'LOVE'를 쓸 때 'L'을 누를 때 'L', 'O'를 누를 때 'O' 를 바로 프로그램에 보여주는 것이 아니라 버퍼에 'L', 'O', 'V', 'E'를 저장해두었다가 버퍼가 가득 차거나 개행문자가 나타나면 버퍼의 내용을 프로그램에 전송하는 것

- BufferedInputStream/BufferedOutputStream은 버퍼를 이용하여 스트림의 입출력 효율을 높히는 보조스트림

- 외부의 입력소스로부터 읽는 것보다 내부의 버퍼로부터 읽는 것이 빨라 효율이 올라감

 

- InputStream의 인스턴스를 입력소스로 함. 

- int size를 통해 버퍼의 사이즈를 지정할 수 있고 크기를 지정하지 않으면 8192byte(8K)크기의 버퍼가 생김

- BufferedInputStream은 버퍼의 크기만큼 입력 소스에서 데이터를 읽어와 버퍼에 저장하는 작업을 반복함

- OutputStream을 출력 소스로 함.

- InputStream과 마찬가지로 int size로 버퍼의 사이즈를 정할 수 있고 지정하지 않으면 8192 byte크기의 버퍼가 생김

- BufferedOutputStream은 write()를 하면 출력이 버퍼에 저장하고 버퍼가 가득차면 버퍼의 모든 내용을 출력.

- 버퍼가 가득 찼을 때만 출력하기 때문에 버퍼에 데이터가 남은 채로 종료될 수 있음

- close()나 flush()를 호출하여 버퍼스트림에 저장된 모든 내용을 출력하게 해야 함

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedOutputStreamEx {
    public static void main(String[] args) {
        try{
            FileOutputStream fos = new FileOutputStream("123.txt");
            BufferedOutputStream bos = new BufferedOutputStream(fos, 5);

            for(int i='1'; i<='9'; i++)
                bos.write(i);

            fos.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

- 위 코드는 FileOutputStream으로 123.txt 파일을 만들고, 버퍼의 크기가 5인 BufferedOutputStream으로 1부터 9까지 출력하는 예제이지만 실제로 실행해보면 1부터 5까지만 저장이 됨 → BufferedOutputStream은 버퍼가 가득 찼을 때만 출력하기 때문에 1부터 5까지 write()했을 땐 버퍼가 가득차서 출력을 했지만 6에서 9까지 write()할 때는 버퍼가 가득 차지 않아 출력하지 못함

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedOutputStreamEx {
    public static void main(String[] args) {
        try{
            FileOutputStream fos = new FileOutputStream("123.txt");
            BufferedOutputStream bos = new BufferedOutputStream(fos, 5);

            for(int i='1'; i<='9'; i++)
                bos.write(i);

            fos.close();
            bos.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

- 남은 6부터 9를 출력하기 위해 위와 같이 코드를 작성 → FileOutputStream의 인스턴스 fos가 close()에 의해 닫힌 뒤 BufferedOutputStream의 인스턴스 bos를 close()하면 오류가 발생함. 보조 스트림이 스트림에 의존적이라는 걸 확인

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedOutputStreamEx {
    public static void main(String[] args) {
        try{
            FileOutputStream fos = new FileOutputStream("123.txt");
            BufferedOutputStream bos = new BufferedOutputStream(fos, 5);

            for(int i='1'; i<='9'; i++)
                bos.write(i);

		    bos.close();
            fos.close();       
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

- BuffredOutputStream의 인스턴스 bos에 close()를 호출하여 버퍼에 저장된 내용을 출력하게 하고 FileOutputStream fos를 close()하니 에러가 발생하지 않고 원하던 대로 1부터 9까지 출력

3.4 SequenceInputStream

- 여러 개의 입력스트림을 하나의 스트림으로부터 데이터를 읽어오는 것처럼 처리할 수 있도록 도와줌

- 큰 파일을 여러 개의 작은 파일로 나누었다가 하나로 합치는 것 같은 작업을 할 때 사용

- FilterInputStream이 아니라 InputStream을 상속

 

 

3.5 PrintStream

- PrintStream은 print, println, printf를 오버로딩하여  데이터를 다양한 형태로 출력

- 문자기반 스트림과 동일한 역할로 JDK1.1부터 PrintWriter를 추가했으나 System.out이 PrintStream이므로 둘다 사용하게 됨

- 다양한 언어를 처리하는데 적합하므로 PrintWriter를 사용하는 것이 좋음