입출력이란?
IO = Input과 Output의 약자
컴퓨터 내부 또는 외부의 장치와 프로그램간의 데이터를 주고받는것
1) 스트림
데이터를 운반하는데 사용되는 연결통로
단방향 통신만 가능. = 하나의 스트림으로 입력과 출력을 동시에 처리할 수 없음.
큐와 같은 구조(선입선출)
2)버퍼
보조스트림은 실제 데이터를 주고받는 스트림이 아니기 때문에 데이터를 입출력할 수 있는 기능은 없으나 스트림의 기능을 향상시키거나 새로운 기능 추가 가능.
→ 따라서 스트림을 먼저 생성한 다음에 보조스트림 생성해야함
→모든 보조 스트림 역시 InputStream 과 OutputStream의 자손임
입력 | 출력 | 설명 |
---|---|---|
FileInputStream | FileOutputStream | 필터를 이용한 입출력 처리 |
BufferedInputStream | BufferedOutputStream | 버퍼를 이용한 입출력 성능향상 |
DataInputStream | DataOutputStream | int, float와 같은 기본형 단위로 데이터를 처리하는 기능 |
SequenceInputStream | 없음 | 두개의 스트림을 하나로 연결 |
LineNumberInputStream | 없음 | 읽어 온 데이터의 라인 번호를 카운트 |
ObjectInputStream | ObjectOutputStream | 데이터를 객체단위로 읽고 쓰는데 사용 |
없음 | PrintStream | 버퍼를 이용하며, 추가적인 print 관련 기능(print, printf, println) |
PushbackInputStream | 없음 | 버퍼를 이용해서 읽어 온 데이터를 다시 되돌리는 기능(unread, push back to buffer) |
3)채널
데이터가 통과하는 쌍방향 통로
→ 채널에서 데이터를 주고 받을 때 사용 되는 것이 버퍼
→ 채널에는 소켓과 연결된 SocketChannel, 파일과 연결된 FileChannel, 파이프와 연결된 Pipe.SinkChannel 과 Pipe.SourceChannel 등이 존재하며, 서버소켓과 연결된 ServerSocketChannel 도 존재
스트림은 바이트단위로 데이터를 전송
입력스트림 | 출력스트림 | 입출력 대상의 종류 |
---|---|---|
FileInputStream | FileOutputStream | 파일 |
ByteArrayInputStream | ByteArrayOutputStream | 메모리(byte배열) |
PipedInputStream | PipedOutputStream | 프로세스(프로세스간의 통신) |
AudioInputStream | AudioOutputStream | 오디오장치 |
java.io패키지를 통해 입출력 관련 클래스 제공
메서드를 통해서 데이터를 읽고 쓸 수 있음
e.g. int read(byte[]b, int off, int len) , void write(byte[]b, int off, int len)
= 입력스트림으로부터 len개의 byte를 읽어서 byte배열 b의 off위치부터 저장
( 추상클래스를(abstract class InputStream) 상속받아서 추상메서드를(abstract int read) 구현한 클래스의 인스턴스에 대해서 추상메서드가 호출되는 것이기 때문에 read()는 반드시 구현되어야하는 핵심적인 메서드임. 따라서 read()없이 int read(byte[]b, int off, int len)는 사용 불가.)
1)InputStream
메서드 | 설명 |
---|---|
read() | 입력 스트림으로부터 1바이트를 읽어서 바이트를 리턴 |
read(byte[] b) | 입력 스트림으로부터 읽은 바이트들을 매개값으로 주어진 바이트 배열 b 에 저장하고 실제로 읽은 바이트 수를 리턴 |
read(byte[] b, int off, int len) | 입력 스트림으로부터 len 개의 바이트만큼 읽고 매개값으로 주어진 바이트 배열 b[off] 부터 len 개까지 저장. 그리고 실제로 읽은 바이트 수인 len 개를 리턴. 만약 len 개를 모두 읽지 못하면 실제로 읽은 바이트 수를 리턴 |
close() | 사용한 시스템 자원을 반납하고 입력 스트림 닫기 |
1)OutputStream
메서드 | 설명 |
---|---|
write(int b) | 출력 스트림으로부터 1바이트를 보낸다.(b 의 끝 1바이트 |
write(byte[] b) | 출력 스트림으로부터 주어진 바이트 배열 b의 모든 바이트를 보낸다. |
write(byte[ ] b, int off, int len) | 출력 스트림으로 주어진 바이트 배열 b[off] 부터 len 개까지의 바이트를 보낸다. |
flush() | 버퍼에 잔류하는 모든 바이트를 출력한다. |
close() | 사용한 시스템 자원을 반납하고 입력 스트림 닫기 |
Byte기반 스트림: 입출력의 단위가 1byte임.
(자바에서는 한 문자를 의미하는 char형이 1 byte가 아니라 2 byte이기 때문에 바이트기반의 스트림으로 2byte인 문자를 처리하는 데는 어려움이 있음. 이를 보완하기 위해 문자 기반의 스트림이 제공됨.)
InputStream → Reader
OutputStream → Writer
1) Byte Stream
2) Character Stream
애너테이션에 대한 기본 정보가 javadoc으로 작성한 문서에 포함되도록함.
표준 입출력 스트림의 종류는 java.lang 패키지의 System 클래스 내부에 static 으로 선언되어 있음
public final class System {
public static final InputStream in;
public static final PrintStream out;
public static final PrintStream err;
....
}
→ System.out 은 콘솔 화면에 문자열을 출력하기 위한 용도로 사용되는 출력 스트림이다.
→ System.in 은 키보드의 입력을 받아들이기 위해서 사용되는 입력 스트림이다.
cf. System.out 과 System.err
둘다 출력 스트림
→ err 은 버퍼링을 지원하지 않음. (err 이 보다 정확하고 빠르게 출력되어야 하기 때문) 버퍼링을 하던 도중 프로그램이 멈추면 버퍼링된 내용은 출력되지 않기 때문
애노테이션 프로세서는 소스코드 레벨에서 소스코드에 붙어있음.
→ 텍스트 파일인 경우 문자 스트림 클래스들을 사용하면 되고, 바이너리 파일인 경우 바이트 스트림을 기본적으로 사용한다.
→ 입출력 효율을 위해 Buffered 계열의 보조 스트림을 함께 사용하는 것이 좋음.
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
String s;
while ((s = br.readLine()) != null) {
bw.write(s + "\n");
}
BufferedInputStream is = new BufferedInputStream(new FileInputStream("a.jpg"));
BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream("b.jpg"));
byte[] buffer = new byte[16384];
while (is.read(buffer) != -1) {
os.write(buffer);
}