Java I/O

입출력

  • 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에 정의된 읽기와 쓰기를 수행하는 메서드

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 비교

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로 출력된다.

Categories:

Updated:

Comments