본문으로 바로가기

Java NIO란

category Back-End/Java 2018. 10. 2. 22:56
반응형


Java NIO에 관하여 좋은 글이 있어 공유합니다.

출처 : http://opennote46.tistory.com

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

NIO (New Input/Output) vs IO (Input/Output) and NIO.2 in Java


Non-blocking I/O (일반적으로 NIO라고 불리우고 때때로 New I/O라고도 함)은 강력한 I/O 오퍼레이션 기능을 제공하는 자바 프로그래밍 API이다.  NIO는 J2SE 1.4에서 표준I/O를 보완하기 위해서 소개되었다.  또 NIO는 확장되어 자바7에 NIO2라고 불리는 새로운 파일시스템 API를 제공한다. 


What Is Input/Output


I/O는 소스로부터 데이터를 읽어서 목적지에 데이터를 읽는 것이다. 데이터는 입력 소스로부터 읽고 출력 목적지로 쓰여진다. 예를 들어 당신이 키보드가 표준 입력으로 동작하면 데이터를 읽어 당신의 프로그램에 쓰여지는 것이다. 표준출력으로 텍스트를 출력하기 위해 System.out.println()를 사용해 본적이 있을 것이다.  당신은 아무 지식없이 I/O를 수행한 것이다.


JDK에 java.io 및 java.nio 패키지에는 I/O를 처리하는 자바클래스들이 포함되어 있다. java.io 패키지는 I/O를 수행하기 위한 굉장히 많은 클래스들을 가지고 있다. 자바 I/O를 배우는 것은 약간 복잡하다. 클래스가 증가하는 수가 관리할 수 없는 지경에 이르는 것을 class explosion이라고 하며, java.io 패키지는 class explosion의 좋은 예제이다.


Input/Output Streams


Stream의 사전적의미는 "무엇인가의 끊기지 않는 흐름"이다. Java I/O에서 스트림의 의미는 데이터의 순차적인 흐름이다. 스트림의 데이터는 바이트, 문자, 객체일 수 있다.


강은 물의 스트림이다. 물은 소스로부터 목적지까지 끊기지않고 흐른다. 비슷하게 Java I/O는 데이터의 흐름이다. Data source로 알려진 소스로부터 data sink로 불리우는 목적지까지 흐른다. 


데이터는 데이터 소스로 부터 자바 프로그램으로 읽어지고, 자바 프로그램은 데이터 싱크로 데이터를 쓴다. 데이터 소스와 자바 프로그램 연결한 스트림을 input stream이라고 한다.  자바 프로그램과 데이터 싱크를 연결한 스트림을 output stream이라고 한다. 


자연에서 예를 들자면 스트림은 소스와 목적지를 물의 흐름으로 연결하지만 자바에서는 자바 프로그램이 input stream과 output stream의 사이에 존재한다. Input 스트림을 통한 데이터 소스로 부터 데이터의 흐름은 자바 프로그램으로 전달되고, 자바 프로그램으로부터 데이터 흐름은 output stream을 통해 데이터 싱크로 전달된다. 다시 말하면 자바 프로그램은 input 스트림으로 데이터를 읽고 output 스트림으로 데이터를 쓴다. 




How we work with input/output stream


데이터 소스로부터 자바 프로그램으로 데이터를 읽기 위해 다음과 같은 단계를 수행한다.


  • 데이터 소스를 지정한다.. 데이터 소스는 파일, 문자열, 배열, 네트워크 연결 등일 수 있다. 
  • 데이터 소스를 사용해 Input 스트림을 생성한다.
  • Input 스트림을 통해 데이터를 읽는다. 일반적으로 입력 스트림으로부터 모든 데이터를 읽을때까지 루프를 수행한다. 입력 스트림의 메소드들은 입력 스트림의 끝이 감지되었을 때, 특정한 문자를 리턴한다.
  • Input 스트림을 닫는다. Input 스트림을 연산을 위해 자신을 연다. 그래서 Input 스트림에서는 스트림을 여는 과장이 묵시적으로 존재한다. 하지만 데이터를 다 읽었으면 input 스트림을 닫아줘야 한다.


자바 프로그램으로 데이터싱크로 데이터를 쓰기 위해선 다음과 같은 단계를 수행한다.


  • 데이터 싱크를 지정한다. 데이터가 쓰여질 목적지를 명시한다. 파일, 문자열, 배열, 네트워크 연결 등일 수 있다.
  • 데이터 싱크를 사용하여 output 스트림을 생성한다.
  • 데이터를 output 스트림으로 쓴다. 
  • Output 스트림을 닫는다. 


Input/output 스트림 클래스는 데코레이터 패턴을 기반으로 한다.


What Is NIO?


스트림 기반 I/O에서는 데이터 소스와 데이터 싱크, 자바 프로그램간의 데이터 이동을 위해서 스트림을 사용한다. 자바 프로그램은 스트림으로부터 데이터를 읽거나 쓴다. 이러한 접근은 I/O 수행을 느리게 만든다. NIO는 스트림 기반 I/O는 느린 속도 문제를 해결한다. NIO에서는 I/O처리를 위해 채널과 버퍼를 사용한다. 채널은 stream과 비슷하다. 채널은 데이터 소스/싱크 및 자바 프로그램간의 연결을 대표한다. 


채널과 스트림사이에는 한가지 차이점이 존재한다.


스트림은 단방향 데이터 전송을 위해 사용된다. 즉, 입력 스트림은 단지 데이터 소스로부터 자바 프로그램으로 데이터를 전송하고, 출력 스트림은 자바 프로그램으로부터 데이터 싱크로 데이터를 전송한다. 하지만, 채널은 양방향 전송 능력을 가지고 있다.


채널은 데이터 읽을 때뿐만 아니라 쓸 때에도 데이터 전송을 위해 사용할 수 있다. 요구에 따라 read-write 채널을 설정할 수 있고, read-only, write-only 채널을 설정할 수 있다.



스트림 기반 I/O에서 데이터 전송의 기본 단위는 byte이다. 그러나 채널기반 NIO에서는 데이터 전송의 기본 단위는 buffer이다. 버퍼는 bounded data container이다. 즉 버퍼는 정해진 용량을 가지고 있다. 스트림 기반 I/O에서는 데이터를 stream에 직접 쓰지만 채널기반 I/O에서는 데이터를 버퍼에 넣는다. 버퍼를 채널로 전달하면, 데이터 싱크로 데이터를 쓸 수 있다. 비슷하게 데이터 소스로부터 데이터을 읽기를 원한다면 채널로 버퍼를 전덩하면 된다. 채널은 데이터 소스로부터 데이터를 읽어서 버퍼로 전달한다. 우리는 버퍼로 부터 데이터를 읽을 수 있다. 위의 다이어그램은 채널, 버퍼, 데이터소스, 데이터싱크, 자바 프로그램 간의 상호 작용을 도식화 한것이다.


New Input/Output 2 (NIO.2)


자바 7에서는 NIO2를 소개하였다. 오리지널 File I/O의 부족함을 보충하기 위해 많은 기능을 제공한다. 이들은 java.nio.file, java.nio.file.attribute 그리고 java.nio.file.spi 패키지에서 찾아 볼 수 있다.


NIO2에서는 모든 파일 시스템을 동일한 방식으로 처리한다. 파일 시스템은 NIO2를 확장해서 제공한다. 또한 파일 시스템에 대한 기본구현을 활용할 수 있고, 파일 시스템 각각 구현체를 사용할 수 있다. 


모든 파일 시스템의 기본 파일 오퍼레이션(copt, move, delete)를 제공한다. 또한 move 오퍼레이션을 제공한다. 또한 향상된 예외 처리를 제공하며, 심볼릭 링크를 제공한다. 


파일이 추가되거나 서브디렉토리가 생기는 것과 같은 디렉토리에 발생하는 이벤트를 처리할 수 있는 서비스를 만들 수 있으며, 파일 트리를 탐색할 수 있는 API도 제공된다.


네트워크 소켓에 대한 비동기 I/O도 제공되며, DatagramChannel을 이용한 멀티캐스팅도 지원한다.


반응형