Java IO
스트림 (Stream) / 버퍼 (Buffer) / 채널 (Channel) 기반의 I/O



스트림, 버퍼, 채널
Stream 기반의 IO

- 데이터가 들어온 순서대로 흘러가는 단방향의 통로 (FIFO)
- 입력 스트림과 출력 스트림을 별도로 사용해야함
- 자바의 모든 기본 I/O
- 동기적, blocking 방식으로 동작
Buffer 기반의 IO

- 임시로 데이터를 담아둘 수 있는 일종의 큐
- 버퍼는 읽고 쓰기가 가능한 메모리 배열
- Stream은 바이트 단위로 매번 read, write를 수행 하여 비효율적임
- Buffer는 중간에서 입력을 모아서 한번에 출력하게 하여 더 효율적임
Channel 기반의 IO

- 데이터가 흘러다니는 양방향의 통로
- input/output 구분하지 않음
- blocking/non-blocking 모두 지원
- 기본적으로 buffer방식
- 채널을 통해서 소켓, 파일 등에 데이터를 전송할 때나 읽어올 때 버퍼를 사용하게 됨으로써 가비지량을 최소화 시킬 수 있게 되며, 이는 가바지 콜렉션 회수를 줄임으로써 서버의 전체 처리량을 증가시켜준다.
채널 | 연결 대상 |
SocketChannel | 소켓 |
FileChannel | 파일 |
Pipe.SinkChannel, Pipe.SourceChannel | 파이프 |
ServerSocketChannel | 서버 소켓 |
IO vs NIO
구분 | IO | NIO |
입출력 방식 | 스트림 | 채널 |
버퍼 방식 | Non-Buffer
→ BufferedXXX 로 지원 | Buffer |
비동기 방식 지원 | X | O |
Blocking/Non-Blocking 방식 | Blocking Only | Both |
사용 케이스 | 연결 클라이언트가 적고, IO 가 큰 경우(대용량) | 연결 클라이언트가 많고, IO 처리가 작은 경우(저용량) |
커널 버퍼 | 직접 핸들링 할 수 없음 | Direct Buffer 로 커널 버퍼를 직접 핸들링가능 (ByteBuffer) |
ㅤ | ㅤ | ㅤ |
ㅤ | ㅤ | ㅤ |
InputStream
, OutputStream
은 바이트 기반 입 출력 스트림이다.바이트기반이라 하는 것은 입출력의 단위가 1byte 라는 의미이다.
InputStream
/** * This abstract class is the superclass of all classes representing * an input stream of bytes. * * Applications that need to define a subclass of InputStream * must always provide a method that returns the next byte of input. */
java.io.InputStream
javadoc- 바이트 기반 입력 스트림의 최상위 추상 클래스
InputStream
subclass 들은 꼭 input의 다음 byte를 반환하는 메서드를 제공해야한다.
모든 read 메서드는 input data가 이용가능할 때까지, stream 혹은 file의 끝이 detected 될 때 까지 혹은 예외가 던져질 때 까지 blocked 된다.
메서드 시그니처 | Desc |
int read( ) | input stream의 다음 바이트를 읽어 정수 (0~255) 로 반환
정상적으로 stream의 끝에 도달하면 -1 반환 |
int read(byte b[ ]) | input stream의 데이터를 읽어 buffer array b 에 저장
읽어 들인 바이트의 숫자를 반환
딱 스트림의 마지막에 도달하여 읽어들일 바이트가 없는 경우 -1 반환
read(b, 0, b.length) |
int read(byte b[ ], int off, int len) | input stream의 데이터를 len개의 바이트 만큼 읽어 b[off] 부터 저장
읽어 들인 바이트의 숫자를 반환
딱 스트림의 마지막에 도달하여 읽어들일 바이트가 없는 경우 -1 반환 |
OutputStream
/** * This abstract class is the superclass of all classes representing * an output stream of bytes. An output stream accepts output bytes * and sends them to some sink. * * Applications that need to define a subclass of OutputStream must always provide at least * a method that writes one byte of output. **/
java.io.OutputStream
javadoc- 바이트 기반 출력 스트림의 최상위 추상 클래스
- OutputStream의 subclass는 output 을 1byte 쓸 수 있는 메서드를 무조건 하나 이상 제공해야함
메서드 시그니처 | Desc |
void write(int b) | output stream으로 부터 1 바이트를 쓴다. |
void write(byte b[ ]) | output stream으로 부터 주어진 바이트 배열 b의 모든 바이트를 쓴다. |
void write(byte b[ ], int off, int len) | output stream으로 부터 b[off] 부터 len 개의 바이트를 보낸다. |
입력스트림의 구현체 | 출력스트림의 구현체 | 입출력 대상의 종류 |
FileInputStream | FileOutputStream | 파일 |
ByteArrayInputStream | ByteArrayOutputStream | 메모리(byte배열) |
PipedInputStream | PipedOutputStream | 프로세스(프로세스간 통신) |
AudioInputStream | AudioOutputStream | 오디오 장치 |
InputStream
/OutputStream
- binary 데이터를 입출력하는 스트림
- 데이터는 1바이트 단위로 처리
- 이미지, 동영상 등을 송수신 할 때 주로 사용

Reader/Writer
- text 데이터를 입출력하는 스트림
- 데이터는 2바이트 단위로 처리
- 일반적인 텍스트 및 JSON, HTML 등을 송수신할 때 주로 사용

- 보조 스트림
- 데코레이터 패턴을 활용하여 바이트 기반, 문자 기반 스트림에 추가적인 기능을 제공함
- e.g.)
- Buffered + (InputStream, OutputStream, Reader, Writer)
- Filter + (InputStream, OutputStream, Reader, Writer)
- ...
표준 스트림 (System.in, System.out, System.err)

public final static InputStream in = null; ... public final static PrintStream out = null; ... public final static PrintStream err = null;
java.lang.System
표준 입출력, 에러에서는
InputStream
, PrintStream
의 구현체로 BufferedInputStream
, BufferedOutputStream
의 인스턴스를 사용함System 클래스의 퍼블릭 정적 필드이므로 그냥 깡으로 다른 InputStream 혹은 OutputStream으로 변경하여 사용할 수 도 있다.
하지만 System 클래스의 정적 메서드를 사용하여 변경하는 것이 더 좋은 방식이다.
메서드 | 설명 |
static void setOut(PrintStream out) | System.out 의 출력을 지정된 PrintStream 으로 변경 |
static void setErr(PrintStream err) | System.err 의 출력을 지정된 PrintStream 으로 변경 |
static void setIn(InputStream in) | System.in의 입력을 지정한 InputStream 으로 변경 |
Java File IO Sample Examples
IO 패키지
→
java.io
→
FileReader
, FileWriter
, FileInputStream
, FileOutputStream
NIO 패키지
→
java.nio.file
→ Path - represents the path to actual file or directory you are willing to work
→ Paths - Path의 유틸리티 클래스

sample code
Path p = Paths.get("D:\\path\\to\\new\\dir"); Path path = Files.createDicrectory(p);
Path path = Paths.get("DataSet/empty-poem.txt"); Path donePath = Files.createFile(path);
Path path = Paths.get("DataSet/poem.txt"); Path donePath = Files.createFile(path); String poem = "하늘을 우러러\n 한점 부끄럼 없거늘\n..."; Files.write(donePath, poem.getBytes(StandardCharsets.UTF_8));
Path path = Paths.get("DataSet/poem.txt"); List<String> lines = Files.readAllLines(path);
@참고)
http://eincs.com - IO vs NIO