///
Search
⌨️

I/O

태그
JAVA

입출력이란?

입, 출력(I/O)이란 Input, Output의 약자로 컴퓨터 내부 또는 외부 장치와 프로그램간의 데이터를 주고 받는 것을 말한다.

알아 보기 전 뭐가 필요할까?

필자가 조사하고 공부하면서 미리 알아두면 좋았을 만한 것을 먼저 적어보려고 한다. 왜냐하면 개념적으로 받아들이는 순서가 너무 안맞아 이것부터 정리하면 좋을 것 같아 보였다. 이유는 역사와 발전과정을 모르니 왜, 뭐가 불편했는지를 모르고 외우게 되었다. 단순하게 동일선에 서있는 기술이라면 차이만 알면 되지만 어쨋건 발전하면서 나온기술이라서 발전과정을 어느정도는 알아야 머리에 정리가 잘되었다. 그리고 설명할때 편하다. “이게 불편하지? 그러니깐 이게 나왔지"와 같이 설명이 된다.
우선적으로 스트림을 알기전 IO 와 NIO에 대해서 먼저 알고 넘어가면 좋을 것 같다.

IO? NIO?

자바는 예전부터 느리다라는 주된 평가가 존재했다. 특히 IO에서는 더더욱 느렸다. 이것을 개선하기 위하여 자바는 1.4 버전부터 새로운 입출력(New Input/Output; NIO) 를 선보였다. 또한 7버전부터는 일관성 없는 IO, NIO를 바로 잡기 위하여 클래스를 바로 잡고, 비동기 채널 등의 네트워크 지원에 힘썼다. 그 덕분에 NIO.2 API가 추가되었다. NIO2는 따로 패키지로 제공되는 것이 아니라 java.nio의 하위 패키지 ../channels, ../charset, ../file 등에 통합되어 있다. 필자 입장에서 가장 헷갈렸던 부분은 IO/NIO의 방식이다.
구분
IO
NIO
입출력 방식
스트림 방식
채널 방식
버퍼 방식
논 버퍼
버퍼
비동기 방식
지원 안 함
지원
블로킹 / 논 블로킹 방식
브로킹 방식만 지원
블로킹 / 논 블로킹 방식 모두 지원
필자의 생각이지만 처음부터 스트림만 배우고 버퍼, 채널 이러한 순서로 공부를 하니 상위 개념을 몰라서 조금 어려운 길로 돌아갔다. 지금 생각해보면 IO/NIO의 차이인데 말이다.

자세한 걸 알아보기 전 차이점?

스트림과 채널의 차이?

IO는 스트림 기반이다. 스트림은 입력 스트림 출력 스트림으로 구분되어 있다. 그래서 단방향으로만 데이터를 보낼 수 있다(그에 따라 두 가지의 스트림을 생성해야한다). NIO는 채널 기반이다. 채널은 스트림과 달리 양방향으로 입력과 출력이 가능하다. 그렇기 때문에 입력과 출력을 위한 별도의 채널을 만들 필요 없이 하나의 채널만 존재해도 된다.

버퍼와 논 버퍼의 차이?

IO에서는 출력 스트림이 1바이트를 쓰면 입력 스트림이 1바이트를 읽는다. 즉시 1을 넣으면 1만 가져간다. 하지만 버퍼에서는 복수 개의 바이트를 한꺼번에 입력 받고 한번에 꺼낸다. 즉 n바이트를 읽는다고 생각하면 좋다. 그래서 스트림을 쌩으로 사용하는 것 보다는 스트림과 버퍼를 조합하여 사용하는 것이 좋다(IO는 버퍼를 제공해주는 보조 스트림인 BufferedInputStream, BufferedOutputStream을 연결해서 사용한다.). 하지만 NIO는 기본적으로 버퍼를 사용해서 입출력을 한다. 즉, 보조적인 역할을 하는 버퍼를 쓸 필요가 없다.

블로킹과 논 블로킹의 차이?

IO는 블로킹된다. 즉, 입력 도중엔 출력이 안되고 출력 도중엔 입력이 안된다. NIO는 블로킹, 논 블로킹의 특징을 모두 가진다. NIO의 경우 스레드를 인터럽트 함으로써 빠져나올 수 있다. 논 블로킹에서는 입출력 작업 준비가 완료된 채널을 선택해서 작업 스레드가 처리하기 때문에 작업 스레드가 블로킹 되지 않는다. 이 방법의 핵심은 멀티플렉서인 Selector 때문이다. 간단히 Selector는 복수 개의 채널 중에서 이벤트가 준비 완료된 채널을 선택하는 방법을 제공해준다.
이전 공부 내용 첨부
이제 위의 표가 이해가 좀 되지 않는가? 여기서 중요한 핵심은 스트림 vs 채널이 아니다. IO에서 new IO(NIO)로 어떻게 발전해왔는지 이다.
1.
IO를 이용하여 입출력을 했다.
2.
IO는 스트림 방식을 사용한다.
3.
스트림은 단방향이라 느렸다. 블로킹이라 다른 작업이 안됐다.
4.
버퍼를 적용했다.
5.
그나마 좀 빨라졌다.
6.
개선을 위하여 스트림에서 사용하기 불편했던 버퍼와 아예 지원 안했던 논 블로킹을 기본적으로 지원하는 new IO를 선보였다.
이제 자세하게 알아보자.

스트림 Stream?

버퍼 Buffer?

채널 Channel?

I/O 컨셉
하드웨어적
Processor controlled memory access Processor가 모든 데이터 전송 처리를 부담
Polling(=Programmed I/O)
I/O장치 순회 확인(=spinLock이랑 비슷함)
busy-waiting(=Polling overhead)
간단함
데이터 전송이 잦은 경우 효율
Interrupt
low overhead
불규칙 요청 처리에 적합
DMA(= Direct Memory Access) I/O 장치와 Memory 사이의 데이터 전송을 Processor 개입 없이 수행 즉, CPU개입 없음
운영체제 관점
I/O scheduling
Error handling
I/O device information managements
Buffering
p - c model을 기준으로 p의 생산 창고
확장 : p의 생산 창고가 가득 찰 때를 대비하여 두 개를 만들 수 있음
Caching
지역성을 이용한 기법
Spooling
각 Program에 대응하는 disk file에 기록(Spooling)
Spooling이 완료되면, Spool을 한번에 하나씩 I/O로 전송