입출력의 개념
1. 입출력이란?
- 컴퓨터 내부 또는 외부의 장치와 프로그램간의 데이터를 주고받는 것을 말한다.
- 예를 들면, 키보드로부터 데이터를 입력 받거나 System.out으로 화면에 출력을 띄우는 것이 있다.
2. 스트림
- 자바에서 입출력을 수행할 때, 어느 한쪽에서 다른 쪽으로 데이터를 전달하기 위해서 스트림을
사용한다.
- 여기서 정의하는 스트림은 데이터를 운반하는데 사용되는 연결통로이므로, 앞에서 다뤘던 스트림과는
다르다.
- 스트림은 물에 비유해서 따온 이름이기에, 한쪽 방향으로만 흐르는 것과 같이 단방향 통신만 가능하다.
그러므로, 입력과 출력을 동시에 처리할 수 없다.
- 만약 동시에 수행하게 할려면, 입력 스트림과 출력 스트림 두 개가 필요하다.
- 스트림은 먼저 보낸 데이터를 먼저 받게 되어 있으며, 중간에 건너뜀 없이 연속적으로 데이터를 주고받는다.
( 큐와 FIFO와 같은 구조이다. )
2-1. 바이트 스트림
- 스트림은 바이트 단위로 데이터를 전송하며 입출력 대상에 따라 아래와 같은 입출력스트림이 있다.
(1) FileInputStream 또는 FileOutputStream
: 파일
(2) ByteArrayInputStream 또는 ByteArrayOutputStream
: 메모리(byte 배열)
(3) PipedInputStream 또는 PipedOutputStream
: 프로세스 (프로세스간의 통신)
(4) AudioInputStream 또는 AudioOutputStream
: 오디오 장치
( 이들은 추상 메서드를 읽고 쓰기 위해 자신에 맞게 아래와 같이 잘 구현해 놓았다. )
InputStream
- abstract int read()
- int read(byte[] b)
- int read(byte[] b, int off, int len)
OutputStream
- abstract void write(int b)
- void write(byte[] b)
- void write(byte[] b, int off, int len)
( 추상 메서드 read()와 write(int b)는 입출력의 대상에 따라 다 다르기 때문에 각 상황에
구현하라고 추상메서드로 정의되어 있다. )
( 추상 메서드 read()와 write(int b)를 제외한 나머지 메서드들은 구현하지 않아도 이들을
사용하면 될 것이라고 생각하지만 아니다. )
( 그 이유는 추상 메서드인 read()와 write(int b)를 이용해서 구현한 것들이기 때문이다. )
( 그래서 read()와 write(int b)를 구현되어 있지 않으면 아무런 의미가 없다. )
( 아래의 예제와 같이 실제 InputStream 클래스의 read()를 사용하는 것을 보자. )
public abstract class InputStream{
...
abstract int read();
// 입력 스트림으로부터 1byte를 읽어서 반환한다. 읽을 수 없으면 -1을 반환한다.
int read(byte[] b, int off, int len){
...
for(int i=off; i<off+len; i++_{
// read()를 호출해서 데이터를 읽어서 배열을 채운다.
b[i] = (byte) read();
}
...
}
// 입력 스트림으로부터 byte배열 b의 크기만큼 데이터를 읽어서 배열 b에 저장한다.
int read(byte[b]){
return read(b, 0, b.length);
}
...
( 실제 InputStream은 아니지만 이해하기 쉽게 변환하였다. )
( read(byte[] b, int off, int len) 메서드에서도 read()를, read(byte[] b)에서도 read()를 직접적으로
부르지는 않지만, 간접적으로 부르고 있다. )
( 그러므로, read()는 반드시 구현되어야하는 핵심적인 메서드이다. )