Java 입문 | java.io 패키지 - 바이트 스트림 | InputStream/OutputStream 추상클래스

InputStream 클래스와 OutputStream 클래스는 추상 클래스이기 때문에 실제 객체를 생성할 수는 없다.

InputStream 클래스

InputStream 클래스는 바이트 스트림의 입력 기능을 제공한다.

InputStream 메소드

InputStream 클래스는 입력 소스로부터 데이터를 읽어오는 메소드를 가지고 있다.

메소드 설명
int available() throws IOException 현재 읽기 가능한 바이트 수를 반환한다.
void close() throws IOException 입력 스트림을 닫는다.
void mark(int readlimit) 입력 스트림에서 현재 위치를 표시한다.
boolean markSupported() 해당 입력 스트림에서 mark()로 지정된 지점이 있는지 여부를 체크한다.
abstract int read() throws IOException 입력 스트림에서 한 바이트를 읽어서 int 값(0~255)으로 반환한다. 더 이상 읽을 값이 없을 경우 -1을 반환한다.
int read(byte[] b) throws IOException byte[] b 만큼의 데이터를 읽어서 b에 저장하고읽은 바이트 수를 반환한다.
int read(byte[] b, int off, int len) thrwos IOException len 만큼을 읽어 byte[] b의 off위치에 저장하고 읽은 바이트 수를 반환한다.
void reset() mark() 를 마지막으로 호출한 위치로 이동한다.
long skip(long n) throws IOException 입력 스트림에서 n 바이트 만큼 데이터를 스킴하고 바이트 수를 반환한다.

InputStream 클래스 중에서 추상 메소드인 read()는 데이터를 입력 위한 메소드이다. read() 메소드는 입력 스트림에서 1byte를 읽어 들이기 위한 메소드인데 EoF(End of File)을 만나면 -1 을 반환하여 읽기 작업이 끝났다는 것을 알린다.

read() 메소드가 1byte씩 읽어 들인다면 read(byte[] b) 메소드는 사용자가 지정한 byte[] 을 이용하여 한꺼번에 원하는 크기를 읽어 온다.

read() 메소드의 반환 데이터 타입형을 보면 byte가 아니라 int이다. 자바는 숫자 체계는 바이트를 기준으로 -128부터 127까지 표현할 수 있다. 하지만 read() 메소드를 통해서 읽는 값은 양수를 기준으로 표현하는데 이 경우에는 0에서 127까지 밖에 사용할 수 없다. 이를 해결하기 위해 더 큰 자료형을 반환하도록 사용하여 0부터 255까지 사용할 수 있게 하고, 음수인 -1을 특수한 입력 값으로 처리하도록 하였다.

available() 메소드는 스트림에서 읽을 수 있는 바이트 수를 얻은 후 이를 기준으로 byte[]를 생성하여 한꺼번에 읽을 수 있다.

OutputStream 클래스

OutputStream 클래스는 바이트 스트림의 출력 기능을 제공한다.

OutputStream 메소드

OutputStream 클래스는 바이트 스트림을 출력하는 메소드를 가지고 있다.

메소드 설명
void close() throws IOException 출력 스트림을 닫는다.
void flush() throws IOException 버퍼에 남은 출력 스트림을 모두 출력한다.
abstract void write(int i) throws IOException 정수 i의 하위 8비트를 출력한다.
void write(byte buf[]) throws IOException buf의 내용을 출력한다.
void write(byte buf[], int index, int size) throws IOException buf의 index 위치부터 size만큼의 바이트를 출력한다.

출력 메소드는 3가지 형태가 있는데, 그 중 첫번째로는 write(int i) 메소드가 있다. 이 메소드 1byte를 출력하는 메소드로써 인자를 byte가 아닌 정수형(0~255)을 받고, 추상 메소드로 선언이 되어 있어서 하위 클래스에서 재정의 되는 메소드이다. write(byte buf[]) 메소드는 byte를 배열로 받아서 출력한다. write(byte buf[], int index, int size) 메소드는 인자로 byte 배열과 함께 시작 위치 및 크기를 받는다.

flush() 메소드는 버퍼(buffer)와 관련이 있는데 버퍼는 입출력을 조금 더 빠르게 도와준다. write 메소드를 호출하여 데이터 출력을 하면 바로 데이터가 출력이 되는 것이 아니라 먼저 버퍼에 쌓인다. 버퍼에 데이터가 어느정도 쌓인 후에 flush() 메소드가 호출 되면 그때서야 데이터가 출력이 되고 버퍼는 비워 버린다. flush() 메소드를 호출하지 않으면 출력 데이터가 버퍼에만 쌓이기 때문에 출력이 되지 않은 경우가 발생할 수 있다. 이런 이유로 보통 하위 클래스에서 자동으로 flush() 메소드가 호출되도록 구현이 된다.