입출력
- Input과 Output의 약자로 컴퓨터 내부 또는 외부 장치와 프로그램간의 데이터를 주고 받는 행위
스트림(Stream)
- 자바에서 어느 한 쪽에서 다른 쪽으로 데이터를 전달하려면, 두 대상을 연결하고 데이터를 전송할 수 있는 연결통로를 스트림이라 정의한다.
- 스트림은 단방향통신으로 하나의 스트림으로 입력과 출력을 동시에 처리할 수 없다.
- 입력과 출력을 동시에 처리하기 위해서는 InputStream과 OutputStream이 필요하다.
- 스트림은 먼저 보낸 데이터를 먼저 받게 되어 있으며 중간에 건너뜀 없이 연속적으로 데이터를 주고 받는다.(Queue와 같은 FIFO)
- java.io 패키지를 통해 제공되며 다루는 데이터 종류에 따라 바이트 기반 스트림, 문자 기반 스트림으로 나눠짐
바이트 기반 스트림
- 바이트단위(1byte) 데이터 전송 입출력 스트림
- Java에서 char형이 2byte이기 때문에 바이트 기반 스트림으로 2byte 문자를 처리하는데에 어려움이 있다.
InputStream |
OutputStream |
I/O target |
FileInputStream |
FileOutputStream |
파일 |
ByteArrayInputStream |
ByteArrayOutputStream |
메모리(byte배열) |
PipedInputStream |
PipedOutputStream |
프로세스(프로세스간 통신) |
AudioInputStream |
AudioOutputStream |
오디오장치 |
위 입출력 스트림은 InputStream, OutputStream의 자손들이며, 각각 읽고 쓰는데 필요한 추상 메서드를 자신에 맞게 구현해놓은 구현체
InputStream |
OutputStream |
abstract int read() |
abstract void write(int b) |
int read(byte[] b) |
void write(byte[] b) |
int read(byte[] b, int off, int len) |
void write(byte[] b, int off, int len) |
read()의 반환타입이 byte가 아닌 int인 이유는 read()의 반환값의 범위가 0 ~ 255와 1이기 때문이다.
문자 기반 스트림
- 바이트기반 입출력 스트림의 단점을 보완하기 위해 문자기반의 스트림 제공
- InputStream, OutputStream 대신 Reader와 Writer로 구성
바이트기반 스트림 |
문자기반 스트림 |
FileInputStream |
FileReader |
FileOutputStream |
FileWriter |
ByteArrayInputStream |
CharArrayReader |
ByteArrayOutputStream |
CharArrayWriter |
PipedInputStream |
PipedReader |
PipedOutputStream |
PipedWriter |
StringBufferInputStream(deprecated) |
StringReader |
StringBufferOutputStream(deprecated) |
StringWriter |
InputStream |
Reader |
abstract int read() |
int read() |
int read(byte[] b) |
int read(char[] cbuf) |
int read(byte[] b, int off, int len) |
abstract int read(char[] cbuf, int off, int len) |
OutputStream과 Writer 비교
OutputStream |
Writer |
abstract void write(int b) |
void write(int c) |
void write(byte[] b) |
void write(char[] cbuf) |
void write(byte[] b, int off, int len) |
abstract void write(char[] cbuf, int off, int len) |
- |
void write(String str) |
- |
void write(String str, int off, int len) |
- 보조스트림 역시 문자기반 보조스트림이 존재하며 사용목적과 방식은 바이트기반 보조스트림과 동일하다.
보조 스트림
- 스트림의 기능을 보완하기 위해 보조스트림을 제공
- 실제 데이터를 주고받는 스트림이 아니기 때문에 데이터를 입출력할 수 있는 기능은 없지만, 스트림의 기능을 향상시키거나 새로운 기능을 추가할 수 있다.
- 스트림을 먼저 생성 후 보조스트림을 생성하여 활용
InputStream |
OutputStream |
설명 |
FilterInputStream |
FilterOutputStream |
필터를 이용한 입출력 처리 |
BufferedInputStream |
BufferedOutputStream |
버퍼를 이용한 입출력 성능향상 |
DataInputStream |
DataOutputStream |
int, float와 같은 Primitive Type으로 데이터를 처리하는 기능 |
SequenceInputStream |
없음 |
두개의 스트림을 하나로 연결 |
LineNumberInputStream |
없음 |
읽어온 데이터의 라인번호를 카운트 (JDK 1.1부터 LineNumberReader로 대체) |
ObjectInputStream |
ObjectOutputStream |
데이터를 객체단위로 읽고 쓰는데 사용 주로 파일을 이용하며 객체 직렬화와 관련 |
없음 |
PrintStream |
버퍼를 이용하며, 추가적인 print관련 기능 (print, printf, println 메서드) |
PushbackInputStream |
없음 |
버퍼를 이용해서 읽어 온 데이터를 다시 되돌리는 기능 (unread, push back to buffer) |
BufferStream을 사용하여 입출력 성능향상
- 한 바이트씩 보내지 않고 버퍼에 담은 후 데이터를 보내기 때문에 시스템 콜의 횟수가 줄어든다.
- OS 레벨의 시스템 콜 횟수가 줄어들기 때문에 성능상 이점이 된다.
FileInputStream fis = new FileInputStream("test.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
// 보조스트림을 이용해 데이터를 읽는다.
bis.read();
- 보조스트림인 BufferedInputStream이 입력 기능을 수행하는 것처럼 보이지만 실제 입력 기능은 BufferedInputStream과 연결된 FileInputStream이 수행한다.
- BufferedInputStream은 버퍼만 제공하여 FileInputStream을 도와주는 역할을 한다.
표준스트림
- 표준스트림은 컴퓨터 프로그래밍에서 표준적으로 입력 받고 출력으로 보내는 데이터와 매체를 총칭하는 용어로 자바(JVM)에서는 System 클래스를 사용한다.
- java.lang.System의 멤버변수인 in, out, err를 이용해서 표준입력, 표준출력, 표준에러를 제공한다.
System.in
- 표준입력스트림, InputStream 타입으로 선언되어 있다.
- System.in은 실제로 객체가 존재하고 있으며 이를 통해 키보드 입력을 받을 수 있다.
- System.in을 통해 접근되는 객체는 JVM이 메모리에 올라오면서 미리 객체를 생성해놓는 대표적인 객체이다. 자료형이 InputStream이기 때문에 바이트단위로만 입출력이 허용된다.
System.out
- 표준출력스트림, PrintStream 타입으로 선언되어 있다.
- PrintStream은 OutputStream 클래스의 후손 클래스로 Exception을 안전하게 처리한 메서드로만 구성되어 있다. 따라서 System.out은 try, catch 구문을 작성할 필요가 없다.
System.err
- 표준에러출력스트림, PrintStream 타입으로 선언되어 있다.
- 일반적으로 System.out과 마찬가지로 모니터로 지정되는 경우가 많다.
- 일반적인 정상출력은 System.out으로 나가고 오류가 발생할 때 알려주어야 할 내용은 System.err로 출력된다.
Comments