보조스트림
보조 스트림의 개념과 종류
보조 스트림
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 - 직접 스트림을 구성해야 하는 등 번거롭지만 속도가 빠름