보조스트림

보조 스트림의 개념과 종류

보조 스트림

Filter Stream, Processing Stream

  • 다른 스트림에 부가적인 기능을 제공하는 스트림
    • 문자 set 변환, Buffering, 기본 데이터 형의 전송, 객체 입출력
  • 스트림 체이닝(Stream Chaining)
    • 필요에 따라 여러 보조 스트림을 연결해서 사용 가능

보조 스트림의 종류

기능 byte 기반 char 기반
byte 스트림을 char 스트림으로 변환 InputStreamReader
OutputStreamWriter
 
버퍼링을 통한 속도 향상 BufferedInputStream
BufferedOutputStream
BufferedREader
BufferedWriter
객체 전송 ObjectInputStream
ObjectOutputStream
 
  • 생성 - 이전 스트림을 생성자의 파라미터에 연결
new BufferedInputStream(System.in);
new DataInputStream(new BufferedInputStream(new FileInputStream()); // Stream Chain
  • 종료 - 보조 스트림의 close()를 호출하면 노드 스트림의 close()까지 호출 됨

사용할 스트림의 결정 과정

노드가 무엇인가 -> 타입은 문자열인가? 바이트인가? -> 방향이 무엇인가?(여기까지 노드 스트림) -> 추가 기능이 필요한가?(보조스트림)

보조스트림 활용

InputStreamReader & OutputStreamWriter

  • byte 기반 스트림을 char 기반으로 변경해주는 스트림
    • 문자열을 관리하기 위해서는 byte 단위보다 char 단위가 유리
    • 키보드에서 입력(byte stream) 받은 데이터를 처리할 경우 등
  • 변환 시 encoding 지정 가능
    InputStreamReader()
  • InputStreamReader(InputStream in) : 기본 char set을 이용해서 InputStreamReader를 생성
  • InputStreamReader(InputStream in, String charsetName) : charsetName을 이용해 InputStreamReader를 생성
  • InputStreamReader(InputStream in, Charset cs) : cs를 이용해 InputStreamReader를 생성
    OutputStreamWriter()
  • OutputStreamWriter(OutputStream out) : 기본 char set을 이용해서 OutputStreamWriter를 생성
  • OutputStreamWriter(OutputStream out, String charsetName) : charsetName을 이용해 OutputStreamWriter를 생성
  • OutputStreamWriter(OutputStream out, Charset cs) : cs를 이용해 OutputStreamWriter를 생성

Buffered 계열

  • 버퍼의 역할
  • 스트림의 입출력 효율을 높이기 위해 버퍼를 사용하는 스트림
    BufferedInputStream()
  • BufferedInputStream(InputStream in) : in을 이용해 크기가 8192인 버퍼를 갖는 BufferedInputStream을 생성
  • BufferedInputStream(InputStream in, int size) : in을 이용해 크기가 size인 버퍼를 갖는 BufferedInputStream을 생성
    BufferedOutputStream()
  • BufferedOutputStream(OutputStream out) : out을 이용해 크기가 8192인 버퍼를 갖는 BufferedOutputStream을 생성
  • BufferedOutputStream(OutputStream out, int size) : out을 이용해 크기가 size인 버퍼를 갖는 BufferedOutputStream을 생성
try (FileInputStream fi = new FileInputStream(src);
    FileOutputStream fo = new FileOutputStream(target);) { // 노드
  copy(fi, fo);
} catch (IOException e) {
  e.printStackTrace();
}

try (BufferedInputStream bi = new BufferedInputStream(new FileInputStream(src));
    BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream(target));) { // 
  copy(bi, bo);
} catch (IOException e) {
  e.printStackTrace();
}
public static void copy(InputStream input, OutputStream output) throws IOException {
long start = System.nanoTime();
byte[] cart = new byte[1024];
int read = -1;
while ((read = input.read(cart)) > 0) {
  output.write(cart, 0, read);
}
long end = System.nanoTime();
System.out.printf("소요 시간: %10dns%n", end - start);
BufferedReader() : readLine() -> 줄 단위로 데이터를 읽어들임
  • BufferedReader(Reader in) : in을 이용해 크기가 8192인 버퍼를 갖는 BufferedReader을 생성
  • BufferedReader(Reader in, int size) : in을 이용해 크기가 size인 버퍼를 갖는 BufferedReader을 생성
    BufferedWriter()
  • BufferedWriter(Writer out) : out을 이용해 크기가 8192인 버퍼를 갖는 BufferedWriter 생성
  • BufferedWriter(Writer out, int size) : out을 이용해 크기가 size인 버퍼를 갖는 BufferedWriter 생성
try (BufferedReader br = new BufferedReader(new FileReader(src));) {
    String line = null;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

객체 직렬화(Serialization)

  • 객체를 파일 등에 저장하거나 네트워크로 전송하기 위해 연속적인 데이터로 변환하는 것
  • 반대의 경우는 역 직렬화(deserialization)
  • 직렬화 되기 위한 조건
    • Serializable 인터페이스를 구현할 것
    • 클래스의 모든 멤버가 Serializable 인터페이스를 구현해야 함
    • 직렬화에서 제외하려는 멤버는 transient 선언
implements Serializable // 필수

private trasient String str; // 직렬화 제외
  • serialVersionUID
    • 클래스의 변경 여부를 파악하기 위한 유일 키
    • 직렬화 할 때의 UID와 역 직렬화 할 때의 UID가 다를 경우 예외 발생
    • 직렬화되는 객체에 UID가 설정되지 않았을 경우 컴파일러가 자동 생성
      • 멤버 변경으로 인한 컴파일 시마다 변경 -> InvalidClassException 초래
    • 직렬화되는 객체에 대해서 serialVersionUID 설정 권장

ObjectInputStream, ObjectOutputStream

  • ObjectInputStream(InputStream in) : in을 이용해 ObjectInputStream 객체를 생성
  • readObject() : 직렬화된 데이터를 역직렬화해서 Object로 리턴한다.

  • ObjectOutputStream(OutputStream out) : out을 이용해 ObjectOutputStream 객체를 생성
  • writeObject(Object obj) : obj를 직렬화해서 출력한다.

Scanner와 BufferedReader

  • char 형태의 데이터를 읽기 위한 클래스들
  • Scanner - 자동 형변환을 지원하는 등 사용이 간편하지만 속도가 느림
  • BufferedReader - 직접 스트림을 구성해야 하는 등 번거롭지만 속도가 빠름