자바에서의 입출력
I/O란? Input과 Output의 약자로 입출력을 의미한다
입출력 : 컴퓨터 내부 또는 외부의 장치와 프로그램 간의 데이터를 주고받는 것이다
입출력의 예 : 키보드로부터 데이터 입력받기, println()으로 화면에 출력
스트림
데이터를 운반하는데 사용되는 연결통로이다
스트림은 단방향통신만 가능하여 입출력을 동시에 할 수 없다
-> 입력 스트림/출력 스트림 2개가 필요
FIFO(First In First Out)구조로 되어있으며 건너뜀 없이 데이터를 연속적으로 주고받는다
바이트기반 스트림 - InputStream OutputStream
스트림은 바이트 단위로 데이터를 전송한다
입력/출력 스트림의 종류
입력스트림 | 출력스트림 | 입출력 대상의 종류 |
FileInputStream | FileOutputStream | 파일 |
ByteArrayInputStream | ByteArrayOutputStream | 메모리(byte배열) |
PipedInputStream | PipedOutputStream | 프로세스(간의 통신) |
AudioInputStream | AudioOutputStream | 오디오 장치 |
자바는 java.io패키지를 통해 많은 입출력관련 클래스들을 제공하고 효준화된 방법을 제공함으로써
입출력의 대상이 달라져도 동일한 방법으로 가능하다
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인 이유는 반환값의 범위가 0~255와 -1이기 때문이다
보조스트림 //스트림의 기능을 보완
실제 데이터를 주고받는 스트림이 아니기 때문에 데이터를 입출력할 수 없다
스트림 생성 후 보조스트림을 생성하여 기능을 향상시키거나 새로운 기능을 추가한다
FileInputStream fis = new FileInputStream(); //기반스트림을 생성한다 BufferedInputStream bis = new BufferedInputStream(fis); //기반스트림을 이용하여 보조스트림을 생성한다 bis.read(); //보조스트림으로부터 데이터를 읽는다 |
보조스트림의 종류
입력 | 출력 | 설명 |
FilterInputStream | FilterOutputStream | 필터를 이용한 입출력 처리 |
BufferedInputStream | BufferedOutputStream | 버퍼를 이용한 입출력 성능향상 |
DataInputStream | DataOutputStream | int, float와 같은 기본형 단위로 데이터를 처리하는 기능 |
SequenceInputStream | x | 두 개의 스트림을 하나로 연결 |
LineNumberInputStream | x | 읽어 온 데이터의 라인 번호를 카운트 (JDK1.1부터 LineNumberReader로 대체) |
ObjectInputStream | ObjectOutputStream | 데이터를 객체단위로 읽고 쓰는데 사용 주로 파일을 이용하며 객체 직렬화와 관련있다 |
x | PrintStream | 버퍼를 이용하며, 추가적인 print 관련 기능(print, printf, println) |
PushbackInputStream | x | 버퍼를 이용해서 읽어 온 데이터를 다시 되돌리는 기능 (unread, push back to buffer) |
문자기반 스트림 - Reader Writer
이전까지는 모두 바이트기반의 스트림이었다(입출력 단위 1byte)
문자 데이터 입출력시에는 Reader와 Writer를 사용한다
InputStream -> Reader / OutputStream -> Writer
바이트 기반 스트림 | 문자기반 스트림 |
FileInputStream FileOutputStream |
FileReader FileWriter |
ByteArrayInputStream ByteArrayOutputStream |
CharArrayReader CharArrayWriter |
PipedInputStream PipedOutputStream |
PipedReader PipedWriter |
StringBufferInputStream StringBufferOutputStream |
StringReader StringWriter |
보조스트림 또한 문자기반 보조스트림이 존재하며 사용목적과 방식은 유사하다
printStream -> printWriter를 제외하면 차이는 위와 동일하다
바이트기반 스트림
InputStream과 OutputStream은 모든 바이트기반 스트림의 조상이다
스트림의 종류에 따라 mark()와 reset()을 사용하여 이미 읽은 데이터를 되돌려 다시 읽을 수 있다
->markSupported()를 통해 기능을 지원하는 스트림인지 확인가능하다
flush()는 버퍼가 있는 출력스트림의 경우에만 의미가 있다
-> OutputStream에 정의되었을때 아무런 일도 하지않는다
**스트림을 사용하여 모든 작업을 마치고 난 후 close()를 호출해서 닫아주어야 한다
ByteArrayInputStream/ByteArrayOutputStream //자주 사용되지는 x
바이트배열에 데이터를 입출력하는데 사용되는 스트림이다
다른곳에 입출력하기 전 데이터를 임시로 바이트배열에 담아서 변환등의 작업을 한다
스트림의 종류가 달라도 읽고 쓰는 방법은 동일하다
바이트 배열은 사용하는 자원이 메모리 밖에 있어 자동적으로 자원을 반환하여 close()를 이용해서 스트림을 닫지 않아도 된다
배열을 이용한 입출력은 작업의 효율을 증가시키므로 가능하면 입출력 대상에 따라 알맞은 크기의 배열을 사용하는 것이 좋다
read()나 write()가 IOException을 발생시킬 수 있기 때문에 try-catch문으로 감싸준다
available() - 블락킹 없이 읽어올 수 있는 바이트의 수를 반환한다
블락킹(blocking) : 데이터를 읽어올 때 데이터를 기다리기 위해 멈춰있는 것
배열의 내용 전체 출력 | 읽어온 만큼(len)만 출력 |
while(input.available() > 0) { input.read(temp); output.write(temp); } |
while(input.available() > 0) { int len = input.read(temp); output.write(temp, 0, len); } |