2. Java I/O 알아보기
Last updated
Last updated
목차
Java의 I/O는 스트림 기반으로 입출력을 처리한다. 스트림은 몇가지 단점을 가지고 있어 Java 1.4부터는 NIO가 등장하였다.
I/O의 스트림과 단점을 알아보자❕
Java I/O는 입출력을 스트림 단위로 한다. 스트림은 Byte 형태로 데이터를 운반하는 통로를 뜻한다. 스트림은 단방향이라 입력/출력 스트림을 따로 만들어주어야한다. 또한 먼저 보낸 데이터를 먼저 수신하는 FIFO 구조(큐)로 되어 있다.
이때 Byte 혹은 Char 단위로 두가지 스트림 방식이 있다.
Byte 단위 (1byte씩 읽는다)
Input/OutputStream가 최상위 부모클래스
ByteArrayInput/OutputStream : byte 배열 입출력
FileInput/OutputStream : 파일 데이터 입출력
Character 단위 (2byte씩 읽는다)
Reader/Writer가 최상위 부모클래스
FileReader/Writer : 문자 기반 파일 입출력
또한 실제 데이터를 주고 받는 스트림은 아니지만, 스트림 기능 향상/추가를 위해 사용하는 보조스트림이 있다.
스트림 생성 후에 보조 스트림을 생성하여 사용한다.
보조 스트림
BufferedInput/OutputStream : 버퍼를 이용한 입출력 성능향상
인풋 데이터를 Buffer에 임시로 담아두고, 한꺼번에 Buffer에 있는 값을 전달한다.
버퍼가 없다면❓ 사용자가 입력하는 순간마다 전달되어 전달되는 횟수가 많다. 즉, 프로그램의 성능 저하를 유발한다.
단, 이때의 버퍼는 커널 버퍼가 아니라 JVM의 버퍼이다 -> 한번 거쳐가기에 속도 느리다.
DataInput/OutputStream : int, float와 같은 기본형 단위로 데이터를 처리
FilterInput/OutputStream : 필터를 이용한 입출력 처리
Java I/O는 스트림 기반으로 이루어진다. 단, 스트림은 몇가지 단점을 가지고 있다.
스트림은 한방향으로 흐른다.
한방향으로 흐르는 통로이기에, 캐시되지 않아 데이터를 앞뒤로 오가면서 원하는 위치에서 읽을 수 없다. 데이터를 시작부터 끝(EOF)까지 순차적으로 읽으며, 한 번 읽고 나면 되돌아갈 수 없다.
I/O는 느리다.
스트림은 동기적/Blocking 방식으로 동작한다. 즉, 스레드가 I/O요청을 받으면 I/O 작업이 완료될 때까지 대기해야 한다. 그리고 Java I/O의 버퍼는 C/C++과 다르게 커널 버퍼에 직접 접근할 수 없다. JVM 내부 버퍼로 복사 후 사용한다. 이 과정에서 속도가 느려진다. ⇒ 자세히
I/O의 이러한 몇가지 단점들을 극복하기 위해 JDK 1.4부터는 NIO가 추가되었다.
다음 장에서 더 자세하게 다루겠지만, NIO가 IO와 다른 점을 간단하게 보면 다음과 같다.
Reference
IO | NIO | |
---|---|---|
입출력 방식
Stream
Buffer
버퍼 방식
Non-Buffer (커널 버퍼X)
Buffer
Blocking/Non-blocking
Blocking IO만 지원
Non-blocking IO/ Blocking IO
동기/비동기
동기만 지원
동기/비동기