Java 파트14-2. 보조 스트림

1. 시작하기 전에


보조 스트림이란 다른 스트림과 연결되어 편리한 기능을 제공해 주는 스트림을 말한다. 보조 스트림은 자체적으로 입출력을 수행할 수 없기 때문에 입출력 스트림에 연결되어 수행되고 문자 변환, 성능 향상, 기본 타입 입출력 등의 기능을 제공한다.
프로그램은 입력 스트림으로부터 직접 데이터를 읽지 않고, 보조 스트림에서 제공하는 기능을 통해 데이터를 읽고, 반대로 프로그램은 출력 스트림으로 직접 데이터를 보내지 않고 보조 스트림에서 제공하는 기능을 이용해 데이터를 보낸다.

2. 보조 스트림 연결하기


보조 스트림은 연속적으로 연결할 수 있다. 주입력 스트림 -> 보조 스트림1 -> 보조 스트림 2 -> 프로그램 -> 보조 스트림1 -> 보조 스트림 2 -> 주 출력 스트림 이렇게 말이다.
보조 스트림을 연결하려면 보조 스트림을 생헝할 때 자신이 연결될 스트림을 생성자의 매개값으로 제공하면 된다.

보조 스트림 변수 = new 보조스트림(연결 스트림)

// 예시
InputStream is = System.in ; // 주 입력스트림
InputStreamReader reader = new InputStreamReader(is) // 보조 스트림
BufferedReader br = new BufferedReader(reader) // 보조 스트림


3. 문자 변환 보조 스트림


바이트 기반 스트림이면서 입출력 데이터가 문자라면 Reader와 Writer로 변환해서 사용하는 것을 고려해야 한다. 왜냐하면 문자 입출력은 Reader와 Writer이 편하기 때문이다.

OutputStreamWriter

바이트 기반 출력 스트림에 연결되어 문자 스트림인 Writer로 변환하는 보조 스트림

// 형식
Writer writer = new OutputStreamWriter(바이트 기반 출력 스트림);

// 예시
FileOutputStream fos = new FileOutputStream("C~~~~"); // 바이트 기반 출력 스트림
Writer writer = new OutputStreamWriter(fos); // Writer 타입으로 변환


InputStreamReader

바이트 기반 입력 스트림에 연결되어 문자 입력 스트림인 Reader로 변환하는 보조 스트림

// 형식
Reader reader = new InputStreamReader(바이트 기반 입력 스트림);

// 예시
FileInputStream fis = new FileInputStream("!!!");
Reader reader = new InputStreamReader(fis);


4. 성능 향상 보조 스트림


프로그램의 실행 성능은 입출력이 가장 늦은 장치를 따라간다. 따라서 cpu와 메모리가 아무리 좋아도 입출력이 늦어지면 성능은 떨어진다. 이에 대한 해결책으로 프로그램이 입출력 소스와 직접 작업하지 않고 중간에 메모리 버퍼와 작업함으로써 실행 성능을 향상시킬 수 있다. 이런 메모리 버퍼를 추가로 제공하는 보조 스트림을 알아보자.

BufferedOutputStream과 BufferedWriter

BufferedOutputStream은 바이트 기반 출력 스트림에, BufferedWriter는 문자 기반 출력 스트림에 연결되어 버퍼를 제공해주는 보조 스트림이다. 프로그램은 버퍼로 고속 전송하고 버퍼는 모아서 한 번에 목적지로 데이터를 전송해주면서 성능 향상의 효과를 얻는다.

BufferedOutputStream bos = new BufferedOutputStream(바이트 기반 출력 스트림);
BufferedWriter bw = new BufferedWriter(문자 기반 출력 스트림);


BufferedInputStream과 BufferedReader

BufferedInputStream은 바이트 기반 입력 스트림에, BufferedReader은 문자 기반 입력 스트림에 연결되어 버퍼를 제공해주는 보조 스트림이다. 입력 소스는 버퍼에 미리 데이터를 채워두고 프로그램은 버퍼로부터 고속으로 데이터를 읽으면서 성능 향상의 효과를 얻는다.

BufferedInputStream bis = new BufferedInputStream(바이트 기반 입력 스트림);
BufferedReader br = new BufferedReader(문자 기반 입력 스트림);


5. 기본 타입 입출력 보조 스트림


DataInputStream과 DataOutputStream 보조 스트림을 연결하면 기본 타입인 boolean, char, short, int, long, float, double을 입출력할 수 있다.

DataInputStream dis = new DataInputStream(바이트 기반 입력 스트림);
DataOutputStream dos = new DataOutputStream(바이트 기반 출력 스트림);
  • DataInputStream / DataOutputStream
    • boolean -> readBoolean() / void -> writeBoolean(boolean v)
    • byte -> readByte() / void -> writeByte(int v)
    • char -> readChar() / void -> writeChar(int v)
    • double -> readDouble() / void -> writeDouble(double v)
    • float -> readFloat() / void -> writeFloat(float v)
    • int -> readInt() / void -> writeInt(int v)
    • long -> readLong() / void -> writeLong(long v)
    • short -> readShort() / void -> writeShort(int v)
    • String -> readUTF() / void -> writeUTF(String str)


6. 프린터 보조 스트림


PrintStream과 PrintWriter는 프린터와 유사하게 출력하는 print, println 메소드를 가지고 있는 보조 스트림이다. System.out이 PrintStream 타입이기에 print, println을 사용할 수 있었다. PrintStream은 바이트 기반 출력 스트림, PrintWriter은 문자 기반 출력 스트림과 연결된다.

PrintStream ps = new PrintStream(바이트 기반 출력 스트림);
PrintWriter pw = new PrintWriter(문자 기반 출력 스트림);


7. 객체 입출력 보조 스트림


ObjectOutputStream과 ObjectInputStream 보조 스트림을 연결하면 메모리에 생성된 객체를 파일 또는 네트워크로 출력할 수 있다. ObjectOutputStream는 객체를 직렬화, ObjectInputStream은 객체를 역직렬화 하는 역할을 한다. 직렬화란 객체를 바이트 배열로 만드는 것을 말하고, 역직렬화는 바이트 배열을 다시 객체로 복원하는 것을 말한다.

ObjectInputStream ois = new ObjectInputStream(바이트 기반 입력 스트림);
객체타입 변수 = (객체타입) ois.readObject(); // 원래 타입으로 복원

ObjectOutputStream oos = new ObjectOutputStream(바이트 기반 출력 스트림);
oos.writeObject(객체); // 객체를 직렬화 해서 출력 스트림으로 보냄

자바는 모든 객체를 직렬화하지 않는다. java.io.Serializable 인터페이스를 구현한 객체만 직렬화한다. Serializable 인터페이스는 메소드 선언이 없는 인터페이스이다. 객체를 파일로 저장하거나, 네트워크로 전송할 목적이라면 개발자는 클래스 선언시 implements Serializable을 추가해야 한다. 이것은 개발자가 JVM에게 직렬화해도 좋다고 승인하는 역할을 한다고 보면 된다.



본 포스팅은 ‘혼자 공부하는 자바’를 읽고 공부한 내용을 바탕으로 작성하였습니다.


© 2021. By Backtony